Oracle中常數複合索引的應用案例

來源:互聯網
上載者:User

從一個客戶的真實最佳化案例引申的問題。

客戶的一個資料庫需要進行最佳化,不過由於程式開發方沒有介入,因此這次最佳化無法對SQL進行修改。

僅對資料庫級的調整一般來說收效不大,不過發現客戶資料庫中個別的SQL存在效能問題,且這個效能問題已經影響到整個資料庫。如果可以將這個SQL最佳化,那麼可以解決目前資料庫的效能問題。幸運的是,這個問題可以通過添加索引來進行最佳化。

類比問題SQL如下:

SQL> select * from v$version;

BANNER

----------------------------------------------------------------

Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production

PL/SQL Release 9.2.0.4.0 - Production

CORE   9.2.0.3.0      Production

TNS for Linux: Version 9.2.0.4.0 - Production

NLSRTL Version 9.2.0.4.0 – Production

SQL> create table t (id number not null, created date, other char(200));

Table created.

SQL> insert into t select rownum, created, 'a' from all_objects;

31126 rows created.

SQL> commit;

Commit complete.

SQL> exec dbms_stats.gather_table_stats(user, 'T')

PL/SQL procedure successfully completed.

SQL> var v_id number

SQL> var v_date varchar2(14)

SQL> explain plan for

2 select count(*)

3 from t

4 where nvl(created, sysdate) > to_date(:v_date, 'yyyymmddhh24miss') - 3

5 and id = :v_id;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------

--------------------------------------------------------------------

| Id | Operation           | Name      | Rows | Bytes | Cost |

--------------------------------------------------------------------

|  0 | SELECT STATEMENT    |            |    1 |   13 |   92 |

|  1 | SORT AGGREGATE     |            |    1 |   13 |      |

|* 2 |  TABLE ACCESS FULL | T          |    1 |   13 |   92 |

--------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - filter(NVL("T"."CREATED",SYSDATE@!)>TO_DATE(:Z,'yyyymmddhh24miss')-3 AND "T"."ID"=TO_NUMBER(:Z))

Note: cpu costing is off

16 rows selected.

對於這個SQL,通過索引方式最佳化很簡單,只需要建立ID和CREATED上的複合索引,就可以避免全表掃描:

SQL> create index ind_t_id_created on t (id, created);

Index created.

SQL> explain plan for

2 select count(*)

3 from t

4 where nvl(created, sysdate) > to_date(:v_date, 'yyyymmddhh24miss') - 3

5 and id = :v_id;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

-------------------------------------------------------------------------------

--------------------------------------------------------------------------

| Id | Operation           | Name            | Rows | Bytes | Cost |

--------------------------------------------------------------------------

|  0 | SELECT STATEMENT    |                  |    1 |   13 |    2 |

|  1 | SORT AGGREGATE     |                  |    1 |   13 |      |

|* 2 |  INDEX RANGE SCAN  | IND_T_ID_CREATED |    1 |   13 |    2 |

--------------------------------------------------------------------------

返回欄目頁:http://www.bianceng.cnhttp://www.bianceng.cn/database/Oracle/

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("T"."ID"=TO_NUMBER(:Z))

filter(NVL("T"."CREATED",SYSDATE@!)>TO_DATE(:Z,'yyyymmddhh24miss')-3)

Note: cpu costing is off

17 rows selected.

Oracle之所以可以選擇索引掃描,是由於複合索引中CREATED列為空白的記錄也會被儲存。由於ID列為非空,而索引不會儲存所有列全為空白的情況,因此CREATED為空白的記錄同樣可以在索引中找到。

事實上,即使ID不為空白,由於另一個查詢條件指定了ID = :V_ID,這使得訪問的記錄並不包括ID為空白的記錄,這使得複合索引仍然可以包括這個SQL需要訪問的所有資料。

不過新的疑問來了,如果查詢的SQL不包含ID列的限制條件,則目前的索引不在可用:

SQL> alter table t modify id null;

Table altered.

SQL> explain plan for

2 select count(*)

3 from t

4 where nvl(created, sysdate) > to_date(:v_date, 'yyyymmddhh24miss') - 3;

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------

--------------------------------------------------------------------

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.