測試背景:生產數據庫的會員表和產品表中存在三個CLOB字段(這些字段主要用來存會員和產品的描述信息),隨着數據量的增長,全表掃描的時候,I/O等待嚴重,於是想到分表!
提出問題:這兩張大表,加起來的索引總共有35個,其中會員表的索引數爲17個,產品表的索引數爲18個(35個索引中不包含LOB字段的索引),這些索引大部分爲組合索引,且存在函數索引(函數索引均爲組合索引的前導列進行desc排序)
索引優化測試:在測試庫中進行優化測試,原始會員表用test代替,用戶schema用hr代替,數據庫版本爲11.2.0.3 32bit on widows2003 enterprise edition
一:建表,添加主鍵約束和組合索引1
- SQL> create table t1 as select * from test;
- SQL> alter table t1 add constraint pk_t1_id primary key (id);
- Table altered.
- SQL> create index idx_t1_mul1 on t1(status,registersource);
- Index created.
二:收集表統計信息,對status字段的空值進行賦值,status字段爲會員的狀態,1爲正常狀態,其他值均爲異常狀態,所以值的分佈傾斜
- SQL> update t1 set status=0 where status is null;
- 4 rows updated.
- SQL> commit;
- Commit complete.
- SQL> exec dbms_stats.gather_table_stats(‘HR’,'T1',CASCADE=>true);
- PL/SQL procedure successfully completed.
- SQL> select status,count(*) from t1 group by status;
- STATUS COUNT(*)
- ---------- ----------
- 1 595612
- 2 1230
- 4 10
- 5 1
- 3 2746
- 0 26825
- 6 rows selected.
三:測試證明結果集比較小的情況下,where字句中包含前導列的時候就會使用組合索引
- SQL> select id,version from t1 where status=0;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 26939 | 289K| 6051 (1)|00:01:13 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 26939 | 289K| 6051 (1)|00:01:13 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 26939 | | 93 (0)|00:00:02 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=0)
四:建組合索引2(組合索引2的字段同組合索引1一樣,只是前導列對調),對registersource字段的空值進行賦值,收集表的統計信息;(該字段用來存儲用戶的註冊來源,值分佈也存在傾斜的情況)
- SQL> create index idx_t1_mul2 on t1(registersource,status);
- Index created.
- SQL> select registersource,count(*) from t1 group by registersource;
- REGIST COUNT(*)
- ------ ----------
- 1 156
- 4
- 3 1689
- 6 4
- 0 23487
- 2 601084
- 6 rows selected.
- SQL> update t1 set registersource=6 where registersource is null;
- 4 rows updated
- SQL>commit;
- Commit complete.
- SQL> exec dbms_stats.gather_table_stats(‘HR’,'T1',CASCADE=>true);
- PL/SQL procedure successfully completed.
五:只查詢registersource字段且結果集小的時候,執行計劃採用組合索引2
- SQL> select * from t1 where registersource='1'; //這裏registersource字段爲varchar2類型,故而加引號
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2744963562
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 227 | 287K| 49 (0)|00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 227 | 287K| 49 (0)|00:00:01 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL2 | 227 | | 3 (0)|00:00:01 |
- ------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("REGISTERSOURCE"='1')
六:傾斜組合測試
- 1:小小
- SQL> select * from t1 where status=0 and registersource=0;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1057 | 1337K| 280 (0)|00:00:04 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1057 | 1337K| 280 (0)|00:00:04 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 1057 | | 68 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=0)
- filter(TO_NUMBER("REGISTERSOURCE")=0)
- SQL> select * from t1 where registersource=0 and status=0;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1057 | 1337K| 280 (0)|00:00:04 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1057 | 1337K| 280 (0)|00:00:04 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 1057 | | 68 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=0)
- filter(TO_NUMBER("REGISTERSOURCE")=0)
- 2:小大
- SQL> select * from t1 where status=0 and registersource=2;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 28531 | 35M| 5776 (1)|00:01:10 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 28531 | 35M| 5776 (1)|00:01:10 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 28531 | | 68 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=0)
- filter(TO_NUMBER("REGISTERSOURCE")=2)
- SQL> select * from t1 where registersource=2 and status=0;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 28531 | 35M| 5776 (1)|00:01:10 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 28531 | 35M| 5776 (1)|00:01:10 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 28531 | | 68 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=0)
- filter(TO_NUMBER("REGISTERSOURCE")=2)
- 3:大小
- SQL> select * from t1 where status=1 and registersource=0;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1106331959
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 21105 | 26M| 4659 (1)|00:00:56 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 21105 | 26M| 4659 (1)|00:00:56 |
- |* 2 | INDEX SKIP SCAN | IDX_T1_MUL2 | 21105 | | 437 (0)|00:00:06 |
- ------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=1)
- filter(TO_NUMBER("REGISTERSOURCE")=0 AND "STATUS"=1)
- SQL> select * from t1 where registersource=0 and status=1;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1106331959
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 21105 | 26M| 4659 (1)|00:00:56 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 21105 | 26M| 4659 (1)|00:00:56 |
- |* 2 | INDEX SKIP SCAN | IDX_T1_MUL2 | 21105 | | 437 (0)|00:00:06 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("STATUS"=1)
- filter(TO_NUMBER("REGISTERSOURCE")=0 AND "STATUS"=1)
- 4:大大
- SQL> select * from t1 where status=1 and registersource=2;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3617692013
- --------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 569K| 703M| 32570 (1)| 00:06:31 |
- |* 1 | TABLE ACCESS FULL| T1 | 569K| 703M| 32570 (1)| 00:06:31 |
- --------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("STATUS"=1 AND TO_NUMBER("REGISTERSOURCE")=2)
- SQL> select * from t1 where registersource=2 and status=1;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3617692013
- --------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 569K| 703M| 32570 (1)| 00:06:31 |
- |* 1 | TABLE ACCESS FULL| T1 | 569K| 703M| 32570 (1)| 00:06:31 |
- --------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("STATUS"=1 AND TO_NUMBER("REGISTERSOURCE")=2)
測試結果表明,cbo將根據結果集的大小來決定使用最優的執行計劃
七:組合索引和其他字段的配合使用(測試結果說明where子句中包含組合索引的前導列,且結果集小的情況下,執行計劃會選擇走組合索引)
- SQL> select * from t1 where status=0 and createddate < sysdate;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1745128362
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 29698 | 36M| 6009 (1)|00:01:13 |
- |* 1 | TABLE ACCESS BY INDEX ROWID| T1 | 29698 | 36M| 6009 (1)|00:01:13 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL1 | 29698 | | 68 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("CREATEDDATE"<SYSDATE@!)
- 2 - access("STATUS"=0)
- SQL> select * from t1 where registersource='0' and createddate < sysdate;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2744963562
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 22302 | 27M| 4514 (1)|00:00:55 |
- |* 1 | TABLE ACCESS BY INDEX ROWID| T1 | 22302 | 27M| 4514 (1)|00:00:55 |
- |* 2 | INDEX RANGE SCAN | IDX_T1_MUL2 | 22302 | | 52 (0)|00:00:01 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("CREATEDDATE"<SYSDATE@!)
- 2 - access("REGISTERSOURCE"='0')
八:函數索引測試,對orderno,membership.status,featured四個字段建組合索引3,同時orderno字段進行desc排序;對前面4個字段建立普通的組合索引4,這種做法意在測試是否有必要使用函數索引?
- SQL> create index idx_t1_mul3 on t1(orderno desc,membership,status,featured);
- Index created.
- SQL> select * from t1 where membership=1 and status=0 order by orderno;
- no rows selected
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 687259109
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 5940 | 7517K| 3009 (1)|00:00:37 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 5940 | 7517K| 3009 (1)|00:00:37 |
- |* 2 | INDEX FULL SCAN DESCENDING| IDX_T1_MUL3 | 5940 | | 1825 (1)|00:00:22 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("MEMBERSHIP"=1 AND "STATUS"=0)
- filter("STATUS"=0 AND "MEMBERSHIP"=1)
- SQL> select * from t1 where membership=1 and status=0 order by orderno desc;
- no rows selected
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 607735922
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 5940 | 7517K| 3009 (1)|00:00:37 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 5940 | 7517K| 3009 (1)|00:00:37 |
- |* 2 | INDEX FULL SCAN | IDX_T1_MUL3 | 5940 | | 1825 (1)|00:00:22 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("MEMBERSHIP"=1 AND "STATUS"=0)
- filter("STATUS"=0 AND "MEMBERSHIP"=1)
- SQL> drop index idx_t1_mul3;
- Index dropped.
- SQL> create index idx_t1_mul4 on t1(orderno,membership,status,featured);
- Index created.
- SQL> select * from t1 where membership=1 and status=0 order by orderno;
- no rows selected
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3155127807
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 5940 | 7517K| 1923 (1)|00:00:24 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 5940 | 7517K| 1923 (1)|00:00:24 |
- |* 2 | INDEX SKIP SCAN | IDX_T1_MUL4 | 5940 | | 739 (0)|00:00:09 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("MEMBERSHIP"=1 AND "STATUS"=0)
- filter("STATUS"=0 AND "MEMBERSHIP"=1)
- SQL> select * from t1 where membership=1 and status=0 order by orderno desc;
- no rows selected
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 893632694
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 5940 | 7517K| 1923 (1)|00:00:24 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 5940 | 7517K| 1923 (1)|00:00:24 |
- |* 2 | INDEX SKIP SCAN DESCENDING| IDX_T1_MUL4 | 5940 | | 739 (0)|00:00:09 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("MEMBERSHIP"=1 AND "STATUS"=0)
- filter("STATUS"=0 AND "MEMBERSHIP"=1)
從測試結果上看,不使用函數索引的效果較優,同時去掉這類的函數索引,會方便今後的shrink table操作
九:不使用前導列情況下,組合索引是否能正常使用?在前面測試函數索引的過程中,where條件中不含前導列,只是對結果集進行排序的時候使用前導列,執行計劃選擇組合索引,因而進行如下測試!
- SQL> create index idx_t1_mul5 on t1(password,signinid);
- Index created.
- SQL> select * from (select signinid,count(*) from t1 group by signinid) where rownum<10;
- SIGNINID COUNT(*)
- ------------------------------------------------------------ ----------
- 000000yu 1
- 0000410265269 1
- 00006789 1
- 00009746 1
- 000113 1
- 0001mwm 1
- 0002081 1
- 000317 1
- 00032156688 1
- 9 rows selected.
- SQL> select * from t1 where signinid='000000yu';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2246799375
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 1296 | 3706 (1)|00:00:45 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 1296 | 3706 (1)|00:00:45 |
- |* 2 | INDEX SKIP SCAN | IDX_T1_MUL5 | 1 | | 3705 (1)|00:00:45 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("SIGNINID"='000000yu')
- filter("SIGNINID"='000000yu')
- SQL> select * from t1 where createddate < sysdate and signinid='000000yu';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 2246799375
- -------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|Time |
- -------------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 1 | 1296 | 3706 (1)|00:00:45 |
- |* 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 1296 | 3706 (1)|00:00:45 |
- |* 2 | INDEX SKIP SCAN | IDX_T1_MUL5 | 1 | | 3705 (1)|00:00:45 |
- -------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("CREATEDDATE"<SYSDATE@!)
- 2 - access("SIGNINID"='000000yu')
- filter("SIGNINID"='000000yu')
從測試結果上看,11.2.0.3版本的數據庫,只要查詢語句中包含組合索引的字段,且結果集較小的情況下,執行計劃會選擇組合索引!
十:在10.2.0.1版本的oracle上進行同樣的測試,發現where子句中不出現組合索引的前導列的時候,執行計劃不會選擇組合索引!
(第9和第10的測試有點疑問,後期將繼續測試,ref http://t.askmaclean.com/viewthread.php?tid=1384&pid=7258&page=1&extra=page%3D1)
- SQL> create user test identified by test;
- User created.
- SQL> grant connect,resource,select_catalog_role to test;
- Grant succeeded.
- SQL> conn test/test
- Connected.
- SQL> create table t1 as select * from dba_objects;
- Table created.
- SQL> create table t1 as select * from dba_objects;
- Table created.
- SQL> desc t1;
- Name Null? Type
- ----------------------------------------- -------- ----------------------------
- OWNER VARCHAR2(30)
- OBJECT_NAME VARCHAR2(128)
- SUBOBJECT_NAME VARCHAR2(30)
- OBJECT_ID NUMBER
- DATA_OBJECT_ID NUMBER
- OBJECT_TYPE VARCHAR2(19)
- CREATED DATE
- LAST_DDL_TIME DATE
- TIMESTAMP VARCHAR2(19)
- STATUS VARCHAR2(7)
- TEMPORARY VARCHAR2(1)
- GENERATED VARCHAR2(1)
- SECONDARY VARCHAR2(1)
- SQL> create index i_t1_mul1 on t1(object_id,object_type);
- Index created.
- SQL> set autot traceonly exp
- SQL> select * from t1 where object_id < 100;
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 1186876071
- -----------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -----------------------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 98 | 17346 | 4 (0)| 00:00:01 |
- | 1 | TABLE ACCESS BY INDEX ROWID| T1 | 98 | 17346 | 4 (0)| 00:00:01 |
- |* 2 | INDEX RANGE SCAN | I_T1_MUL1 | 98 | | 2 (0)| 00:00:01 |
- -----------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - access("OBJECT_ID"<100)
- Note
- -----
- - dynamic sampling used for this statement
- SQL> select * from t1 where object_type='INDEX';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3617692013
- --------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 531 | 93987 | 159 (2)| 00:00:02 |
- |* 1 | TABLE ACCESS FULL| T1 | 531 | 93987 | 159 (2)| 00:00:02 |
- --------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("OBJECT_TYPE"='INDEX')
- Note
- -----
- - dynamic sampling used for this statement
- SQL> set autot off
- SQL> select count(*) from t1;
- COUNT(*)
- ----------
- 50380
- SQL> select object_type,count(*) from t1 group by object_type;
- OBJECT_TYPE COUNT(*)
- ------------------- ----------
- CONSUMER GROUP 5
- INDEX PARTITION 276
- SEQUENCE 143
- QUEUE 27
- SCHEDULE 1
- TABLE PARTITION 128
- RULE 4
- JAVA DATA 306
- PROCEDURE 85
- OPERATOR 57
- LOB PARTITION 1
- OBJECT_TYPE COUNT(*)
- ------------------- ----------
- WINDOW 2
- LOB 566
- PACKAGE 848
- PACKAGE BODY 791
- LIBRARY 150
- RULE SET 19
- PROGRAM 12
- TYPE BODY 173
- CONTEXT 5
- JAVA RESOURCE 770
- XML SCHEMA 26
- OBJECT_TYPE COUNT(*)
- ------------------- ----------
- TRIGGER 171
- JOB CLASS 2
- UNDEFINED 6
- DIRECTORY 9
- DIMENSION 5
- MATERIALIZED VIEW 2
- TABLE 1636
- INDEX 1800
- SYNONYM 20026
- VIEW 3671
- FUNCTION 270
- OBJECT_TYPE COUNT(*)
- ------------------- ----------
- WINDOW GROUP 1
- JAVA CLASS 16417
- INDEXTYPE 10
- CLUSTER 10
- TYPE 1926
- RESOURCE PLAN 3
- EVALUATION CONTEXT 14
- JOB 6
- 41 rows selected.
- SQL> set autot traceonly exp
- SQL> select /*+index(i_t1_mul1)*/ * from t1 where object_type='INDEX';
- Execution Plan
- ----------------------------------------------------------
- Plan hash value: 3617692013
- --------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- --------------------------------------------------------------------------
- | 0 | SELECT STATEMENT | | 531 | 93987 | 159 (2)| 00:00:02 |
- |* 1 | TABLE ACCESS FULL| T1 | 531 | 93987 | 159 (2)| 00:00:02 |
- --------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 1 - filter("OBJECT_TYPE"='INDEX')
- Note
- -----
- - dynamic sampling used for this statement
綜上所述:
1:可以對線上數據庫的組合索引做優化,對於傾斜字段做前導列的組合索引,可以使用非傾斜字段做前導列,或者建立相同的索引,前導列對調;
2:取消相應的函數索引
3:刪除不必要的組合索引,對經常在where子句中出現的字段建組合索引(例如查詢1中where子句出現A,B,C,D四個字段,查詢2中where子句出現A,B,C三個字段,且這個查詢語句經常出現,這種條件下,只需要對A,B,C,D字段建組合索引即可,無需建2個索引)
4:注意索引的熱點塊問題,前面3的場景在併發嚴重的情況下,有可能會導致出現熱點快,因而需要根據需求來適當調整