CHAR型別函式索引導致結果錯誤
今天在PUB上看到了一個錯誤,在10.2.0.1上建立CHAR型別的SUBSTR函式索引後,可能導致隨後的查詢得到錯誤的結果:http://www.itpub.net/thread-1163703-1-1.html
測試發現問題在10.2.0.3中也存在:
SQL> CREATE TABLE T_CHAR (COL1 CHAR(5));
表已建立。
SQL> INSERT INTO T_CHAR VALUES ('111');
已建立 1 行。
SQL> CREATE INDEX IND_T_CHAR_COL1 ON T_CHAR (SUBSTR(COL1, 1, 1));
索引已建立。
SQL> SELECT * FROM T_CHAR;
COL1
-----
111
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
未選定行
現在問題已經出現了,正常情況下是可以訪問到記錄的,看來是由於函式索引導致的問題:
SQL> SET AUTOT ON
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 3849968283
-------------------------------------------------------------------------------------------
| Id | Operation |Name |Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID|T_CHAR | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN |IND_T_CHAR_COL1| 1 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"='111')
2 - access(SUBSTR("COL1",1,1)='1')
Note
-----
- dynamic sampling used for this statement
統計資訊
----------------------------------------------------------
0 recursive calls
0 db block gets
1 consistent gets
0 physical reads
0 redo size
166 bytes sent via SQL*Net to client
232 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
SQL> SELECT /*+ FULL(T_CHAR) */ * FROM T_CHAR WHERE COL1 = '111';
COL1
-----
111
執行計劃
----------------------------------------------------------
Plan hash value: 2185307396
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T_CHAR | 1 | 7 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"='111' AND SUBSTR("T_CHAR"."COL1",1,1)='1')
Note
-----
- dynamic sampling used for this statement
統計資訊
----------------------------------------------------------
4 recursive calls
0 db block gets
15 consistent gets
0 physical reads
0 redo size
227 bytes sent via SQL*Net to client
239 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
當前的版本為10.2.0.3:
SQL> SET AUTOT OFF
SQL> SELECT * FROM V$VERSION;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Solaris: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
檢查11g是否修正了這個bug:
SQL> CONN YANGTK/YANGTK@YTK111
已連線。
SQL> SELECT * FROM V$VERSION;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for 32-bit Windows: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
SQL> CREATE TABLE T_CHAR (COL1 CHAR(5));
表已建立。
SQL> INSERT INTO T_CHAR VALUES ('111');
已建立 1 行。
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
COL1
-----
111
SQL> CREATE INDEX IND_T_CHAR_COL1 ON T_CHAR(SUBSTR(COL1, 1, 1));
索引已建立。
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
未選定行
SQL> SET AUTOT ON EXP
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 1935535116
--------------------------------------------------------------------------------------------
| Id | Operation |Name |Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID|T_CHAR | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN |IND_T_CHAR_COL1| 1 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"='111')
2 - access(SUBSTR("COL1",1,1)='1')
Note
-----
- dynamic sampling used for this statement
11.1.0.6中居然也有這個錯誤。查詢了一下metalink,在文件Doc ID: 5739162.8中描述了這個錯誤,Oracle在11.2和11.1.0.7中fixed了這個問題:
SQL> conn TEST/TEST@db01
已連線。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
SQL> CREATE TABLE T_CHAR (COL1 CHAR(5));
表已建立。
SQL> INSERT INTO T_CHAR VALUES ('111');
已建立 1 行。
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
COL1
----------
111
SQL> CREATE INDEX IND_T_CHAR_COL1 ON T_CHAR(SUBSTR(COL1, 1, 1));
索引已建立。
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
COL1
----------
111
SQL> SET AUTOT ON EXP
SQL> SELECT * FROM T_CHAR WHERE COL1 = '111';
COL1
----------
111
執行計劃
----------------------------------------------------------
Plan hash value: 1935535116
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| T_CHAR | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IND_T_CHAR_COL1 | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1"='111')
2 - access(SUBSTR("COL1",1,1)='1')
Note
-----
- dynamic sampling used for this statement
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-596536/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mysql索引型別建立錯誤導致SQL查詢緩慢MySql索引型別
- sql最佳化-錯誤強制型別轉換導致索引失效SQL型別索引
- Oracle隱式型別轉換導致索引失效Oracle型別索引
- 多餘索引導致explain錯誤索引AI
- FIRST_ROWS優化模式訪問遠端表可能導致錯誤結果(二)優化模式
- FIRST_ROWS優化模式訪問遠端表可能導致錯誤結果(一)優化模式
- 資料型別與函式索引-PostgreSQL篇資料型別函式索引SQL
- 資料型別與函式索引-MySQL篇資料型別函式索引MySql
- 資料型別與函式索引-Oracle篇資料型別函式索引Oracle
- struts 結果型別型別
- 請別誤用 TypeScript 過載函式型別TypeScript函式型別
- 錯誤資料導致優化器不識別(高階優化手法用盡,結果盡然是這樣)優化
- 資料型別隱式轉換導致的阻塞資料型別
- C++模板函式實現型別推導C++函式型別
- Go 函式多返回值錯誤處理與error 型別介紹Go函式Error型別
- DUMP函式結果的意思函式
- 【函式】Oracle EXTRACT()函式與to_char() 函式函式Oracle
- oracle to_char 函式Oracle函式
- oracle to_char函式Oracle函式
- 利用函式索引,最佳化因cluster factor過高導致不走索引一例函式索引
- impdp時parallel=4導致的錯誤Parallel
- 評“MySQL 隱式轉換引起的執行結果錯誤”MySql
- TypeScript 函式型別TypeScript函式型別
- MySQL 因資料型別轉換導致執行計劃使用低效索引MySql資料型別索引
- const char* 型別不能用於初始化char* 型別實體型別
- PHP弱型別在實戰中導致的漏洞總結PHP型別
- MySQL bit型別增加索引後查詢結果不正確案例淺析MySql型別索引
- C++中出現《E0144 "const char *" 型別的值不能用於初始化 "char *" 型別的實體》的錯誤解決方法C++型別
- sql中使用函式導致cost高SQL函式
- Malwarebytes安全更新如何導致錯誤地識別惡意軟體
- MySQL:MySQL客戶端快取結果導致OOMMySql客戶端快取OOM
- 使用ROWNUM將導致查詢結果集的固化
- mybatis引數型別錯誤MyBatis型別
- 預定義錯誤型別型別
- js函式回撥錯誤JS函式
- react 報錯 元素隱式具有 "any" 型別,因為型別為 "string" 的表示式不能用於索引型別 "{}"。 在型別 "{}" 上找不到具有型別為 "string" 的引數的索引簽名。React型別索引
- printf函式用錯格式符的後果函式
- merge語句導致的ORA錯誤分析