1. 程式人生 > 實用技巧 >Oracle索引欄位發生隱式轉換仍然能夠使用索引

Oracle索引欄位發生隱式轉換仍然能夠使用索引

Oracle索引欄位發生隱式轉換仍然能夠使用索引

前言

最近在優化SQL過程中,發現執行計劃中,某張表使用了索引但是根據執行計劃謂詞資訊部分,發現該索引被隱式轉換了。

在我以前的認知中,索引欄位被隱式轉換後是用不了索引的,因此自己構造如下實驗做測試。

環境構造

14:43:47 SYS@zkm(17)> create user zkm identified by oracle;                              

User created.

Elapsed: 00:00:00.05
14:43:54 SYS@zkm(17)> grant dba to zkm;

Grant succeeded. Elapsed: 00:00:00.01 14:43:59 SYS@zkm(17)> create table zkm.t ( n1 char(20),n2 char(20),n3 char(30)); Table created. Elapsed: 00:00:00.10 14:44:07 SYS@zkm(17)> insert into zkm.t values('1','1','1'); 1 row created. Elapsed: 00:00:00.01 14:44:10 SYS@zkm(17)> insert into zkm.t values('2','2','2');
1 row created. Elapsed: 00:00:00.00 14:44:14 SYS@zkm(17)> commit; Commit complete. Elapsed: 00:00:00.00 14:44:16 SYS@zkm(17)> create index zkm.idx on zkm.t(n1); Index created. Elapsed: 00:00:00.05 14:44:21 SYS@zkm(17)> analyze table zkm.t compute statistics; Table analyzed. Elapsed: 00:00:00.11

過程

14:48:45 SYS@zkm
(17)> conn zkm/oracle Connected. 14:48:52 ZKM@zkm(17)> set line 500 14:48:57 ZKM@zkm(17)> set autot traceo exp 14:49:03 ZKM@zkm(17)> select /*+ index(t IDX) */ * from zkm.t where n1=1; Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 70 | 3 (0)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T | 1 | 70 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(TO_NUMBER("N1")=1) 14:49:11 ZKM@zkm(17)> select /*+ index(t IDX) */ * from zkm.t where n1='1'; Elapsed: 00:00:00.00 Execution Plan ---------------------------------------------------------- Plan hash value: 2770274160 ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 70 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 70 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IDX | 1 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("N1"='1')

這個時候發現並不能模擬出想要的結果。

當n1=1的時候,根據謂詞資訊可以得知,此時n1被做了隱式轉換。

於此同時,並沒法使用索引了。

研究了很久還是甚覺不解,於是將生產遇到的問題在群裡問問看大神們。

於是,根據下表,hint換成index_ffs再試試看。

索引 索引範圍掃描 索引跳躍掃描 索引快速全掃描
index index_rs index_ss index_ffs
index_asc no_index_rs no_index_ss no_index_ffs
index_desc index_rs_asc index_ss_asc index_asc
  index_rs_desc index_ss_desc index_desc

發光時代