列类型和变量类型不一致引起的性能问题?

    一条不能再简单的SQL引起了性能问题, Where条件中只有一个列, 并且有索引, 这是为什么呢? 请看下面的例子:

SQL> CREATE TABLE T_OBJECTS
  2  (
  3    COL1 NUMBER, COL2 VARCHAR2(20), COL3 VARCHAR2(30)
  4  );

Table created.

SQL> CREATE INDEX IDX_T_OBJECTS_1 ON T_OBJECTS(COL1);

Index created.

SQL> CREATE INDEX IDX_T_OBJECTS_2 ON T_OBJECTS(COL2);

Index created.

SQL> INSERT INTO T_OBJECTS SELECT
  2  OBJECT_ID, OBJECT_ID, OBJECT_NAME FROM DBA_OBJECTS;

9506 rows created.

SQL> COMMIT;

    在COL1上使用时可以正确地使用索引, 将1500用单引号括起来也行:

ASQL> EXPLAIN PLAN
    2   SELECT * FROM T_OBJECTS WHERE COL1=1500;

SQLPLAN                                                    
------------------------------------------------------------
  0     SELECT STATEMENT Optimizer=ALL_ROWS                
  1   0   TABLE ACCESS (BY INDEX ROWID) OF T_OBJECTS (TABLE)
  2   1     INDEX (RANGE SCAN) OF IDX_T_OBJECTS_1 (INDEX)  

    在COL2上使用时并不能使用索引, 这是因为Oracle将Where条件变成了"TO_NUMBER(COL2)=1500"来执行, 在9i上还有可能出现Index Full Scan的情况.

ASQL> EXPLAIN PLAN
    2   SELECT * FROM T_OBJECTS WHERE COL2=1500;

SQLPLAN                                            
---------------------------------------------------
  0     SELECT STATEMENT Optimizer=ALL_ROWS        
  1   0   TABLE ACCESS (FULL) OF T_OBJECTS (TABLE)  

ASQL> EXPLAIN PLAN
    2   SELECT /*+ INDEX_ASC(T_OBJECTS) */ * FROM T_OBJECTS
    3   WHERE COL2=1500;

SQLPLAN                                            
---------------------------------------------------
  0     SELECT STATEMENT Optimizer=ALL_ROWS        
  1   0   TABLE ACCESS (FULL) OF T_OBJECTS (TABLE)  

    使用绑定变量时, 虽然Plan会显示是Index Range Scan, 但其实Consistent Gets和Index Full Scan一样.

留言 (2)

大哥,这个问题已经被人家阐述了很多次了:)

呵呵,再提提也有必要,很多人犯这个错误
http://tomszrp.itpub.net/post/11835/59921

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • Have you seen Kate lately?
  • 最近你看见凯特了吗?
  • No, I have no contact with her.
  • 没有. 我和她没有一点儿联系.
  • I heard she got married last week.
  • 我听说她上星期结婚了.
  • Oh, how nice. Sorry, I've got to go now.
  • 那真好. 对不起, 我必须得走了.
  • So do I. See you later. Keep in touch.
  • 我也是, 再见. 记得联系哦.