SQL 語句調優_SQL傳遞引數的資料型別與表索引欄位型別保持一致
今天在一個生產資料庫上發現了一個TOP SQL,SQL 本身很簡單,但COST 非常大(執行計劃走了全表掃描),SQL語句如下:
SELECT D.FIELD_VALUE, D.FIELD_VALUE_CLOB FROM RUNLOG_RUN_REC_DETAIL D WHERE D.RUN_RECORD_ID =:B2 AND D.FIELD_NUMBER=:B1
這個表在欄位"RUN_RECORD_ID"上建立了索引,但為什麼沒有使用到索引呢?
一. 原因
傳遞引數時,型別與資料庫表的欄位型別不同(表欄位型別為字元型),這樣就會產生資料型別轉換,ORACLE無法使用到索引,走了TABLE ACCESS FULL,導致get buffer過多,cpu cost也過多:
Object Type TABLE
Order 1
Rows 1
Size (KB) 0.052
Cost 7,328
Time 88
CPU Cost 804,127,446
I/O Cost 7,286
二. 解決方法
1. 修改SQL 語句,建議:
SELECT D.FIELD_VALUE, D.FIELD_VALUE_CLOB FROM PROD_RUNLOG_RUN_REC_DETAIL D WHERE TO_NUMBER(D.RUN_RECORD_ID) =:B2 AND D.FIELD_NUMBER=:B1 ;
2. 修改傳遞引數的型別為字元型
:B2='2007' 而不是 :B2=2007
SELECT D.FIELD_VALUE, D.FIELD_VALUE_CLOB FROM PROD_RUNLOG_RUN_REC_DETAIL D WHERE D.RUN_RECORD_ID =:B2 AND D.FIELD_NUMBER=:B1 ;
3. 修改該表的其中一個索引(推薦)
DROP INDEX SCDC.RUN_RECORD_ID;
CREATE INDEX SCDC.RUN_RECORD_ID ON TABLE SCDC.PROD_RUNLOG_RUN_REC_DETAIL(TO_NUMBER(RUN_RECORD_ID),FIELD_NUMBER);
三. 結論
當SQL 傳遞引數與表索引欄位型別不一致的時候,ORACLE 將自動進行資料型別轉換,這時就不會使用到索引,而是使用全表掃描,從而導致了CPU 和I/O 都開銷很大。筆者已經遇到了多次這樣的問題,今天寫出來,希望對大家有所幫助。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/32980/viewspace-676870/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- sql語句修改欄位型別和增加欄位SQL型別
- sqlite sql 修改欄位型別SQLite型別
- 保留兩位小數:資料庫欄位型別NUMBER,Java欄位型別Double型別資料庫型別Java
- mysql 用sql語句查詢一個表中的所有欄位型別、註釋MySql型別
- 【SQL】SQL資料型別SQL資料型別
- SQL SERVER 查詢表的欄位名、資料型別和最大長度SQLServer資料型別
- 細說SQL SERVER中欄位型別SQLServer型別
- SQL 資料型別SQL資料型別
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-有限制的子型別SQL資料型別
- 【MySQL】MySQL基礎(SQL語句、約束、資料型別)MySql資料型別
- 修改表的欄位型別型別
- 資料欄位型別匹配型別
- Java資料型別與資料庫欄位型別對應關係Java資料型別資料庫
- 【轉】修改表的欄位資料型別的方法資料型別
- PLSQL Language Referenc-SQL資料型別-子型別與基型別具有相同的資料型別家族SQL資料型別
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-使用者定義的PL/SQL子型別SQL資料型別
- SQL SERVER與C#的資料型別對應表SQLServerC#資料型別
- 主流資料庫欄位型別轉.Net型別的方法資料庫型別
- 【PL/SQL】使用變數傳遞方法生成表更名的SQL語句SQL變數
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-LONG和LONG RAW變數SQL資料型別變數
- 修改欄位資料型別的方法資料型別
- 【SQL】18 SQL NULL 函式、SQL 通用資料型別、SQL 用於各種資料庫的資料型別SQLNull函式資料型別資料庫
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-ROWID和UROWID變數SQL資料型別變數
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-CHAR和VARCHAR2變數SQL資料型別變數
- 如何處理sql server中的image型別的欄位?SQLServer型別
- Oracle-不刪表資料,修改欄位型別Oracle型別
- mybatis sql String>Double, 型別引數被強轉為數值型別MyBatisSQL型別
- SQL Server-資料型別SQLServer資料型別
- SQL 常見資料型別SQL資料型別
- SQL Server資料型別BLOBSQLServer資料型別
- SQL Server中獲取資料庫名、表名、欄位名和欄位註釋的SQL語句SQLServer資料庫
- 【SQL】16 SQL CREATE INDEX 語句、 撤銷索引、撤銷表以及撤銷資料庫、ALTER TABLE 語句、AUTO INCREMENT 欄位SQLIndex索引資料庫REM
- PLSQL Language Reference-PL/SQL資料型別-SQL資料型別-不同的最值大小SQL資料型別
- MYSQL SET型別欄位的SQL操作知識介紹MySql型別
- mybatis 得sql語句對應簡單型別MyBatisSQL型別
- SQL SERVER 資料庫查詢表和欄位資訊語句SQLServer資料庫
- SQL資料型別和C#資料型別間的轉換SQL資料型別C#
- (轉) JAVA,Mybatis,Oracle變數型別與欄位型別不一致,分割槽表全掃的優化JavaMyBatisOracle變數型別優化