|
|
 |
 |
 |
 |
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:
> 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 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
<cristian.cudi @yahoo.it> wrote: >On May 11, 8:50 am, Steve Chien <stevech @wisagetech.com> wrote: >> 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 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
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:
> On 11 May 2007 00:00:03 -0700, Cristian Cudizio > <cristian.cudi@yahoo.it> wrote: > >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: > >> 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 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 > 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
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
<cristian.cudi @yahoo.it> wrote: >On May 11, 9:06 am, Steve Chien <stevech @wisagetech.com> wrote: >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio >> <cristian.cudi@yahoo.it> wrote: >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> 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 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 >> 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 >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
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:
> On 11 May 2007 00:09:08 -0700, Cristian Cudizio > <cristian.cudi@yahoo.it> wrote: > >On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote: > >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio > >> <cristian.cudi@yahoo.it> wrote: > >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> 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 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 > >> 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 > >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 > Hi, > I dropped the orignal index and did, > c > 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
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
<cristian.cudi @yahoo.it> wrote: >On May 11, 9:23 am, Steve Chien <stevech @wisagetech.com> wrote: >> On 11 May 2007 00:09:08 -0700, Cristian Cudizio >> <cristian.cudi@yahoo.it> wrote: >> >On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio >> >> <cristian.cudi@yahoo.it> wrote: >> >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> >> 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 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 >> >> 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 >> >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 >> Hi, >> I dropped the orignal index and did, >> c >> 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 >Yes, >create index normally, >create index ak2_str1_mytest on mytest(str1)) ; >Bye >Cristian Cudizio >http://oracledb.wordpress.com >http://cristiancudizio.wordpress.com
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:
> On 11 May 2007 00:41:48 -0700, Cristian Cudizio > <cristian.cudi@yahoo.it> wrote: > >On May 11, 9:23 am, Steve Chien <stevech@wisagetech.com> wrote: > >> On 11 May 2007 00:09:08 -0700, Cristian Cudizio > >> <cristian.cudi@yahoo.it> wrote: > >> >On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio > >> >> <cristian.cudi@yahoo.it> wrote: > >> >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> >> 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 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 > >> >> 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 > >> >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 > >> Hi, > >> I dropped the orignal index and did, > >> c > >> 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 > >Yes, > >create index normally, > >create index ak2_str1_mytest on mytest(str1)) ; > >Bye > >Cristian Cudizio > >http://oracledb.wordpress.com > >http://cristiancudizio.wordpress.com > 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 |
... read more »
On 11 May 2007 01:09:51 -0700, Cristian Cudizio
<cristian.cudi @yahoo.it> wrote: >On May 11, 10:06 am, Steve Chien <stevech @wisagetech.com> wrote: >> On 11 May 2007 00:41:48 -0700, Cristian Cudizio >> <cristian.cudi@yahoo.it> wrote: >> >On May 11, 9:23 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> On 11 May 2007 00:09:08 -0700, Cristian Cudizio >> >> <cristian.cudi@yahoo.it> wrote: >> >> >On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio >> >> >> <cristian.cudi@yahoo.it> wrote: >> >> >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: >> >> >> >> 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 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 >> >> >> 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 >> >> >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 >> >> Hi, >> >> I dropped the orignal index and did, >> >> c >> >> 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 >> >Yes, >> >create index normally, >> >create index ak2_str1_mytest on mytest(str1)) ; >> >Bye >> >Cristian Cudizio >> >http://oracledb.wordpress.com >> >http://cristiancudizio.wordpress.com >> 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
... read more »
On May 11, 11:02 am, Steve Chien <stevech @wisagetech.com> wrote:
> On 11 May 2007 01:09:51 -0700, Cristian Cudizio > <cristian.cudi@yahoo.it> wrote: > >On May 11, 10:06 am, Steve Chien <stevech@wisagetech.com> wrote: > >> On 11 May 2007 00:41:48 -0700, Cristian Cudizio > >> <cristian.cudi@yahoo.it> wrote: > >> >On May 11, 9:23 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> On 11 May 2007 00:09:08 -0700, Cristian Cudizio > >> >> <cristian.cudi@yahoo.it> wrote: > >> >> >On May 11, 9:06 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> >> On 11 May 2007 00:00:03 -0700, Cristian Cudizio > >> >> >> <cristian.cudi@yahoo.it> wrote: > >> >> >> >On May 11, 8:50 am, Steve Chien <stevech@wisagetech.com> wrote: > >> >> >> >> 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 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 > >> >> >> 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 > >> >> >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 > >> >> Hi, > >> >> I dropped the orignal index and did, > >> >> c > >> >> 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 > >> >Yes, > >> >create index normally, > >> >create index ak2_str1_mytest on mytest(str1)) ; > >> >Bye > >> >Cristian Cudizio > >> >http://oracledb.wordpress.com
... 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
<cristian.cudi @yahoo.it> wrote: >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',CASCAD E=>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
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...
>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
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"
<richard.fo @bigpond.nospam.com> wrote: >"Cristian Cudizio" <cristian.cudi @yahoo.it> wrote in message > news:1178880528.448552.76480@w5g2000hsg.googlegroups.com... >>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 >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
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
<stevech @wisagetech.com> wrote: >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
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:
>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
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...
> On Fri, 11 May 2007 12:41:24 GMT, "Richard Foote" > <richard.fo @bigpond.nospam.com> wrote: >>"Cristian Cudizio" <cristian.cudi@yahoo.it> wrote in message >>news:1178880528.448552.76480@w5g2000hsg.googlegroups.com... >>>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 >>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 > 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%';
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
|
 |
 |
 |
 |
|