Home     |     Java    |     Php General    |     Oracle Database    |     Oracle Server  

MS Dynamics CRM 3.0

  •  Setting up and Configuring Microsoft Dynamics CRM 3.0
  •  Managing Security and Information Access
  •  Entity Customization: Concepts and Attributes
  •  Entity Customization: Forms and Views
  •  Entity Customization: Relationships, Custom Entities, and Site Map
  •  Reporting and Analysis
  •  Workflow
  •  Server-Side SDK
  •  Client-Side SDK
  •  Integration with External Applications
  • Cervo Technologies
    The Right Source to Outsource

    Sharepoint Portal Server KB

    Microsoft CRM Info

    WPF Interview Questions

    SilverLight Interview Qs

    Asp.Net 2.0 Interview Qs

    Asp.NET 1.1 FAQs

    Oracle Interview Questions

    SAP Interview Questions

    Oracle Server

    Oracle 10g2 LIKE operator and case-insensitive issues


    Hi,

      We're curerrently facing some performance issues related to the
    "LIKE" operator in Oracle 10g2. Here is what we encountered.

      We have a Oracle 10g2 database which has the following
    characteristics.

    NLS_CHARACTERSET => AL32UTF8
    NLS_NCHAR_CHARACTERSET => AL16UTF16
    NLS_RDBMS_VERSION => 10.2.0.1.0

      We created a table like below.
    -- creates test table
    CREATE TABLE MYTEST
    (id NUMBER(10, 0) NOT NULL,
     str1 VARCHAR2(128) NOT NULL,
     str2 NVARCHAR2(128) NOT NULL);

      Then, we populated with some random data.
    -- PL/SQL for creating random data
    BEGIN
      DBMS_RANDOM.SEED('thisisjustatest');
      FOR i IN 1 .. 100000 LOOP
        INSERT INTO MYTEST VALUES(i, DBMS_RANDOM.STRING('P', 64),
    DBMS_RANDOM.STRING('P', 64));
      END LOOP;
      INSERT INTO MYTEST VALUES(100001, 'steve', 'chien');
      INSERT INTO MYTEST VALUES(100002, 'STEVE', 'CHIEN');
    END;

      Afterwards, we created the indexes.
    -- creates indexes
    CREATE INDEX AK1_ID_MYTEST ON MYTEST(ID);
    CREATE INDEX AK2_STR1_MYTEST ON MYTEST(STR1);
    CREATE INDEX AK3_STR2_MYTEST ON MYTEST(STR2);

      With the "autotrace" turned on , NLS_COMP set to BINARY, and
    NLS_SORT set to BINARY in SQLPlus, we did two experiments.

    CASE I.
    select * from mytest where str1 = 'steve'

    Plan hash value: 587925449

    --------------------------------------------------------------------------- --------------------
    | Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------- --------------------
    |   0 | SELECT STATEMENT            |                 |     1 |   209 |     5   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| MYTEST          |     1 |   209 |     5   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | AK2_STR1_MYTEST |     1 |       |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------- --------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       2 - access("STR1"='steve')

    CASE II.
    select * from mytest where str1 like 'steve%';

    Plan hash value: 587925449

    --------------------------------------------------------------------------- --------------------
    | Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------- --------------------
    |   0 | SELECT STATEMENT            |                 |     1 |   209 |     5   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| MYTEST          |     1 |   209 |     5   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | AK2_STR1_MYTEST |     1 |       |     3   (0)| 00:00:01 |
    --------------------------------------------------------------------------- --------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       2 - access("STR1" LIKE 'steve')

      Here is what bothered us more... We actually wanted to do
    case-insensitive searches & sorts on columnes str1 & str2. We dropped
    the indexes and re-created them as blows.

    - drop & re-create indexes
    DROP INDEX AK1_ID_MYTEST;
    DROP INDEX AK2_STR1_MYTEST;
    DROP INDEX AK3_STR2_MYTEST;

    - creates indexes
    CREATE INDEX AK1_ID_MYTEST ON MYTEST(ID)
    CREATE INDEX AK2_STR1_MYTEST ON MYTEST(NLSSORT(STR1,
    'NLS_SORT=GENERIC_M_CI'));
    CREATE INDEX AK3_STR2_MYTEST ON MYTEST(NLSSORT(STR2,
    'NLS_SORT=GENERIC_M_CI'));

      With "autotrace" turned on, NLS_COMP set to LINGUISTIC, and NLS_SORT
    set to GENERIC_M_CI in SQLPlus, we dir the following two test cases.

    CASE I.
    select * from mytest where str1 = 'steve'

    Plan hash value: 3883648009

    ------                              -
    -----------------------------------------
    | Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    ------                              -
    -----------------------------------------
    |   0 | SELECT STATEMENT            |                 |   851 |   173K|   404   (1)| 00:00:05 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| MYTEST          |   851 |   173K|   404   (1)| 00:00:05 |
    |*  2 |   INDEX RANGE SCAN          | AK2_STR1_MYTEST |   340 |       |     3   (0)| 00:00:01 |
    ------                              -
    -----------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       2 - access(NLSSORT("STR1",'nls_sort=''GENERIC_M_CI''')=HEXTORAW('
                  024F025501FE026101FE00000202020202') )

    CASE II.
    select * from mytest where str1 like 'steve%';

    Plan hash value: 1692938441

    ------                    - -----------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ------                    - -----------------------------------------
    |   0 | SELECT STATEMENT  |        |    32 |  6688 |   791   (1)| 00:00:10 |
    |*  1 |  TABLE ACCESS FULL| MYTEST |    32 |  6688 |   791   (1)| 00:00:10 |
    ------                    - -----------------------------------------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("STR1" LIKE 'steve%')

      Oracle was using the "TABLE ACCESS FULL" to handle the "LIKE"
    operator. It's extremely slow and we wondered why it couldn't use the
    "INDEX RANGE SCAN" anymore.

      Thanks for any suggestion!

    - Steve

    On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote:

    On asktom.oracle.com you can find useful information about Oracle db
    case sensitive. However
    from 10gR2 you can use
    NLS_COMP = LINGUISTIC
    NLS_SORT = BINARY_CI

    it make searches case insensitive

    Bye
     Cristian Cudizio

    http://oracledb.wordpress.com
    http://cristiancudizio.wordpress.com

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 00:00:03 -0700, Cristian Cudizio

    Hi,

      We did try the BINARY_CI too. However, the outstanding question is
    that the Oracle was not using the index with the "LIKE" operator.

      Any suggestion?

      Thanks!

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote:

    Yes, hear me, use
    NLS_COMP = LINGUISTIC
    NLS_SORT = BINARY_CI

    it works on 10gR2

    Bye
     Cristian Cudizio

    http://oracledb.wordpress.com
    http://cristiancudizio.wordpress.com

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 00:09:08 -0700, Cristian Cudizio

    Hi,

      I dropped the orignal index and did,

    create index ak2_str1_mytest on mytest(nlssort(str1,
    'NLS_SORT=BINARY_CI')) COMPUTE STATISTICS;

      With "autotrace" turned on, NLS_COMP set to LINGUISTIC, and NLS_SORT
    set to BINARY_CI in SQLPlus, we ran the following test again.

     select * from mytest where str1 like 'steve%';

      We got the following plan,

    Plan hash value: 1692938441

    --------------------------------------------------------------------------- -
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------- -
    |   0 | SELECT STATEMENT  |        |    32 |  6688 |   791   (1)| 00:00:10 |
    |*  1 |  TABLE ACCESS FULL| MYTEST |    32 |  6688 |   791   (1)| 00:00:10 |
    --------------------------------------------------------------------------- -

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("STR1" LIKE 'steve%')

    Note
    -----
       - dynamic sampling used for this statement

      Still "TABLE ACCESS FULL SCAN"... Did I miss anything?

      Thanks!

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    On May 11, 9:23 am, Steve Chien <stevech@wisagetech.com> wrote:

    Yes,
    create index normally,
    create index ak2_str1_mytest on mytest(str1)) ;

    Bye
    Cristian Cudizio

    http://oracledb.wordpress.com
    http://cristiancudizio.wordpress.com

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 00:41:48 -0700, Cristian Cudizio

    Hi,

      We dropped the index and recreated as below.

    create index ak2_str1_mytest on mytest(str1) COMPUTE STATISTICS;

      With "autotrace" turned on, NLS_COMP set to LINGUISTIC, and NLS_SORT
    set to BINARY_CI, we still got the following plan.

    select * from mytest where str1 like 'steve%';

    Plan hash value: 1692938441

    --------------------------------------------------------------------------- -
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------- -
    |   0 | SELECT STATEMENT  |        |     2 |   418 |   791   (1)| 00:00:10 |
    |*  1 |  TABLE ACCESS FULL| MYTEST |     2 |   418 |   791   (1)| 00:00:10 |
    --------------------------------------------------------------------------- -

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("STR1" LIKE 'steve%')

    Note
    -----
       - dynamic sampling used for this
    ...

    read more »

    On May 11, 10:06 am, Steve Chien <stevech@wisagetech.com> wrote:

    ...

    read more »

    On 11 May 2007 01:09:51 -0700, Cristian Cudizio

    ...

    read more »

    On May 11, 11:02 am, Steve Chien <stevech@wisagetech.com> wrote:

    ...

    read more »

    I have to review my test, there is something wrong, i've observed
    strange behaviurs,
    but lastli i've a test case.
    I'm testing on 10.2.0.2 on Linux suse el x86 64 bit.
    Connesso a:
    Oracle Database 10g Release 10.2.0.2.0 - 64bit Production

    SQL> drop index idxtestcase;

    Indice eliminato.

    SQL> CREATE INDEX IDXTESTCASE ON AUTENTI (AUTECOGNOME);

    Indice creato.

    SQL> exec
    dbms_stats.gather_table_stats(OWNNAME=>'GEOCALL',tabname=>'AUTENTI',CASCADE =>TRUE);

    Procedura PL/SQL completata correttamente.

    SQL> alter Session set nls_comp=linguistic;

    Modificata sessione.

    SQL> alter Session set nls_sort=binary_ci;

    Modificata sessione.

    SQL> alter session set optimizer_mode=first_rows_1;

    Modificata sessione.

    SQL> set autotrace on
    SQL> SELECT AUTECOGNOME,ACTION FROM AUTENTI WHERE AUTECOGNOME LIKE
    'cudiz%';

    AUTECOGNOME
    --------------------------------------------------------------------------- -----
        ACTION
    ----------
    CUDIZIO

    Piano di esecuzione
    ----------------------------------------------------------
    Plan hash value: 3571430138

    --------------------------------------------------------------------------- --
    | Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)|
    Time     |
    --------------------------------------------------------------------------- --
    |   0 | SELECT STATEMENT  |         |     1 |    22 |     5   (0)|
    00:00:01 |
    |*  1 |  TABLE ACCESS FULL| AUTENTI |     1 |    22 |     5   (0)|
    00:00:01 |
    --------------------------------------------------------------------------- --

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("AUTECOGNOME" LIKE 'cudiz%')

    Statistiche
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
             16  consistent gets
              0  physical reads
              0  redo size
            402  bytes sent via SQL*Net to client
            338  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed

    SQL> alter session set optimizer_mode=all_rows;

    Modificata sessione.

    SQL> SELECT AUTECOGNOME,ACTION FROM AUTENTI WHERE AUTECOGNOME LIKE
    'cudiz%';

    AUTECOGNOME
    --------------------------------------------------------------------------- -----
        ACTION
    ----------
    CUDIZIO

    Piano di esecuzione
    ----------------------------------------------------------
    Plan hash value: 3571430138

    --------------------------------------------------------------------------- --
    | Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)|
    Time     |
    --------------------------------------------------------------------------- --
    |   0 | SELECT STATEMENT  |         |     1 |    22 |     5   (0)|
    00:00:01 |
    |*  1 |  TABLE ACCESS FULL| AUTENTI |     1 |    22 |     5   (0)|
    00:00:01 |
    --------------------------------------------------------------------------- --

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("AUTECOGNOME" LIKE 'cudiz%')

    Statistiche
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
             16  consistent gets
              0  physical reads
              0  redo size
            402  bytes sent via SQL*Net to client
            338  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed

    SQL> SELECT /*+ INDEX(A IDXTESTCASE) */ AUTECOGNOME,ACTION FROM
    AUTENTI A WHERE AUTECOGNOME LIKE 'cu
    diz%';

    AUTECOGNOME
    --------------------------------------------------------------------------- -----
        ACTION
    ----------
    CUDIZIO

    Piano di esecuzione
    ----------------------------------------------------------
    Plan hash value: 3801628502

    --------------------------------------------------------------------------- -----
    -----------

    | Id  | Operation                   | Name        | Rows  | Bytes |
    Cost (%CPU)|
     Time     |

    --------------------------------------------------------------------------- -----
    -----------

    |   0 | SELECT STATEMENT            |             |     1 |    22
    |     5   (0)|
     00:00:01 |

    |   1 |  TABLE ACCESS BY INDEX ROWID| AUTENTI     |     1 |    22
    |     5   (0)|
     00:00:01 |

    |*  2 |   INDEX FULL SCAN           | IDXTESTCASE |     1 |
    |     3   (0)|
     00:00:01 |

    --------------------------------------------------------------------------- -----
    -----------

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       2 - filter("AUTECOGNOME" LIKE 'cudiz%')

    Statistiche
    ----------------------------------------------------------
              1  recursive calls
              0  db block gets
              5  consistent gets
              0  physical reads
              0  redo size
            402  bytes sent via SQL*Net to client
            338  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed

    SQL> alter session set optimizer_mode=first_rows;

    Modificata sessione.

    SQL> SELECT AUTECOGNOME,ACTION FROM AUTENTI WHERE AUTECOGNOME LIKE
    'cudiz%';

    AUTECOGNOME
    --------------------------------------------------------------------------- -----
        ACTION
    ----------
    CUDIZIO

    Piano di esecuzione
    ----------------------------------------------------------
    Plan hash value: 3571430138

    --------------------------------------------------------------------------- --
    | Id  | Operation         | Name    | Rows  | Bytes | Cost (%CPU)|
    Time     |
    --------------------------------------------------------------------------- --
    |   0 | SELECT STATEMENT  |         |     1 |    22 |     5   (0)|
    00:00:01 |
    |*  1 |  TABLE ACCESS FULL| AUTENTI |     1 |    22 |     5   (0)|
    00:00:01 |
    --------------------------------------------------------------------------- --

    Predicate Information (identified by operation id):
    ---------------------------------------------------

       1 - filter("AUTECOGNOME" LIKE 'cudiz%')

    Statistiche
    ----------------------------------------------------------
              0  recursive calls
              0  db block gets
             16  consistent gets
              0  physical reads
              0  redo size
            402  bytes sent via SQL*Net to client
            338  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed

    Probably i didn't notice when i first made my test that Oracle makes
    an INDEX FULL SCAN
    so my suggestions were not correct. It make searches case insensitve
    but it seems not able to
    use the normal indexes.
    So i remand on asktom.oracle.com and his suggestions

    Bye
    Cristian Cudizio

    http://oracledb.wordpress.com
    http://cristiancudizio.wordpress.com

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 03:48:48 -0700, Cristian Cudizio

      Thanks for your time. I'll see if anyone can help on the NEWSGROUP
    and try to post it to ASKTOM.

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    "Cristian Cudizio" <cristian.cudi@yahoo.it> wrote in message

    news:1178880528.448552.76480@w5g2000hsg.googlegroups.com...

    Hi Cristian / Steve

    Basic Oracle indexes use binary sort mode and therefore can't be used if
    nls_sort is not set to binary ...

    Cheers

    Richard

    -----------------------------------------------Reply-----------------------------------------------

    On Fri, 11 May 2007 12:41:24 GMT, "Richard Foote"

    Hi Richard,

      How about the information I mentioned in my first POST? I created
    the indexs like,

    create index ak2_str1_mytest on mytest(nlssort(str1,
    'NLS_SORT=GENERIC_M_CI'));

      When NLS_COMP=LINGUISTIC & NLS_SORT=GENERIC_M_CI, the index can be
    applied to

    select * from mytest where str1 = 'steve';

      However, the index was not used for

    select * from mytest where str1 like 'steve%';

      Any suggestion?

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    On Fri, 11 May 2007 14:50:13 +0800, Steve Chien

      BTW, I looked at the article in asktom. It looked like there there
    is no easy way for "LIKE" to work with functional-based index (like
    nlssort).

    http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1...

      Any insight?  Thanks in advance!

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    Steve Chien wrote:
    > Hi,

    >   We're curerrently facing some performance issues related to the
    > "LIKE" operator in Oracle 10g2. Here is what we encountered.

    Hmmm and the reason just not to use function based index is?...

    Gints Plivna
    http://www.gplivna.eu

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 07:57:12 -0700, Gints Plivna <gints.pli@gmail.com>
    wrote:

    >Steve Chien wrote:
    >> Hi,

    >>   We're curerrently facing some performance issues related to the
    >> "LIKE" operator in Oracle 10g2. Here is what we encountered.

    >Hmmm and the reason just not to use function based index is?...

    >Gints Plivna
    >http://www.gplivna.eu

      We used the nlssort to create the indexes. Actually, it's
    function-based index. When you have NLS parameters set properly, the
    Oracle can rewrite your query and use it as needed.

      It did work with the "=", but not the "LIKE".

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    Steve Chien wrote:
    >   It did work with the "=", but not the "LIKE".

    > - Steve

    But you can explicitly do that. Of course it means you have to modify
    your application code (if it has not been done from the very
    begginning):

    SQL> create table t (name varchar2(100));

    Table created.

    SQL> insert into t select object_name from dba_objects;

    55640 rows created.

    SQL> create index t_idx on t (upper(name));

    Index created.

    SQL> exec dbms_stats.gather_table_stats(user, 't')

    PL/SQL procedure successfully completed.

    SQL> set autot on
    SQL> set autot traceonly
    SQL> select * from t where upper(name) like 'CONT%';

    11 rows selected.

    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=2 Bytes=48)
       1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=3 Card=
              2 Bytes=48)

       2    1     INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=2 Card=2)

    Or the same with variables:

    SQL> variable x varchar2(100)
    SQL> begin
      2    :x := 'cont';
      3  end;
      4  /

    PL/SQL procedure successfully completed.

    SQL> select * from t where upper(name) like upper(:x)||'%';

    11 rows selected.

    Execution Plan
    ----------------------------------------------------------
       0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=54 Card=2782 Bytes
              =66768)

       1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=54 Card
              =2782 Bytes=66768)

       2    1     INDEX (RANGE SCAN) OF 'T_IDX' (INDEX) (Cost=4 Card=501)

    Gints Plivna
    http://www.gplivna.eu

    -----------------------------------------------Reply-----------------------------------------------

    On 11 May 2007 23:42:21 -0700, Gints Plivna <gints.pli@gmail.com>
    wrote:

      Initially, the application was developed against MS SQLServer, so we
    didn't have the "upper" in place. That's what we're trying to avoid...

      If that's the last resort, we might really need to do so... Really
    wonder why Oracle 10g couldn't deal this kind of issues with NLS
    completely...

      Tks!

    - Steve

    -----------------------------------------------Reply-----------------------------------------------

    "Steve Chien" <stevech@wisagetech.com> wrote in message

    news:s2q8439a2iiofaj35gmlf47t8u7fdj58lg@4ax.com...

    Hi Steve

    Unfortunately, you can't perform an *indexed* LIKE search with NLS_COMP set
    to LINGUISTIC.

    This is clearly documented in the Globalization Support Guide:

    http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14225/c...

    where it specifically  states:

    "The SQL functions MAX( ) and MIN( ), and also the LIKE operator, cannot use
    linguistic indexes when NLS_COMP is set to LINGUISTIC."

    Coincidently, I've recently been approached with the possibility of
    presenting a series of seminars on the huge general topic of Oracle Indexing
    in Europe sometime later in the year. I'll be sure to include some
    information on case-insensitive searches as it's something that appears to
    have generated some interest (and disappointments).

    Cheers

    Richard

    Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc