高效的SQL【Composite Indexes(最佳前導列的選擇)】
Composite Indexes(最佳前導列的選擇)
一、前導列是否有序對composite indexes的影響大
1、建立表t1(x,y) x有序列,y隨意列
doudou@TEST> begin
2 for i in 1.. 1000000 loop
3 insert into t1 values (i,to_char(dbms_random.random,'999999999999') );
4 if mod(i,100000)=0
5 then
6 commit;
7 end if;
8 end loop;
9 end;
10 /
PL/SQL procedure successfully completed.
2、組合索引:前導列是否有序的列對clustering_factor影響大。
doudou@TEST> create index idx_t1_01 on t1(x,y) ;
Index created.
doudou@TEST> create index idx_t1_02 on t1(y,x);
Index created.
doudou@TEST> select index_name,table_name,clustering_factor from user_indexes where table_name='T1';
INDEX_NAME TABLE_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
IDX_T1_02 T1 999562
IDX_T1_01 T1 2402
doudou@TEST> drop index idx_t1_02;
Index dropped.
3、資料相同的2個表,不同前導列的組合索引,檢視效率
doudou@TEST> create table t2 as select * from t1;
Table created.
doudou@TEST> create index idx_t2_01 on t2(y,x);
Index created.
doudou@TEST> select index_name,table_name,clustering_factor from user_indexes where table_name='T2';
INDEX_NAME TABLE_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
IDX_T2_01 T2 999591
doudou@TEST> select index_name,table_name,clustering_factor from user_indexes where table_name='T1';
INDEX_NAME TABLE_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
IDX_T1_01 T1 2402
sys@TEST> alter system flush shared_pool; --(生產庫慎用,會造成大量物理讀)
System altered.
doudou@TEST> exec dbms_stats.gather_table_stats('DOUDOU','T1',cascade=>true); --(cascade=>true收集統計索引資訊,預設為flase)
PL/SQL procedure successfully completed.
doudou@TEST> exec dbms_stats.gather_table_stats('DOUDOU','T2',cascade=>true);
PL/SQL procedure successfully completed.
3-1、等值查詢
doudou@TEST> select count(*) from t1 where x=1 and y=-1481404810;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 1645197104
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 12 | | |
|* 2 | INDEX RANGE SCAN| IDX_T1_01 | 1 | 12 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("X"=1 AND "Y"=(-1481404810))
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t2 where x=1 and y=-1481404810;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 3050965404
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 12 | | |
|* 2 | INDEX RANGE SCAN| IDX_T2_01 | 1 | 12 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("Y"=(-1481404810) AND "X"=1)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
【clustering_factor高低,對index rang scan 模式。等值查詢影響不大。】
3-2、where 謂語使用“<和>”
doudou@TEST> select count(*) from t1 where x<10 and y>0;
COUNT(*)
----------
4
Execution Plan
----------------------------------------------------------
Plan hash value: 1645197104
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 12 | | |
|* 2 | INDEX RANGE SCAN| IDX_T1_01 | 1 | 12 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("Y">0 AND "X"<10)
filter("Y">0)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t2 where x<10 and y>0;
COUNT(*)
----------
4
Execution Plan
----------------------------------------------------------
Plan hash value: 3321871023
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 542 (1)| 00:00:07 |
| 1 | SORT AGGREGATE | | 1 | 12 | | |
|* 2 | TABLE ACCESS FULL| T2 | 1 | 12 | 542 (1)| 00:00:07 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("X"<10 AND "Y">0)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2417 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
【clustering_factor高低,對index rang scan 模式。where 謂語使用“<和>”,clustering_factor對索引影響大】
二、前導列選擇度高低對composite indexes的影響小
1、t3,t4資料相同 x列選擇度高,y列選擇低
doudou@TEST> create index idx_t3_01 on t3(x,y);
Index created.
doudou@TEST> create index idx_t4_01 on t4(y,x);
Index created.
doudou@TEST> select index_name,table_name,clustering_factor from user_indexes where table_name='T3';
INDEX_NAME TABLE_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
IDX_T3_01 T3 995325
doudou@TEST> select index_name,table_name,clustering_factor from user_indexes where table_name='T4';
INDEX_NAME TABLE_NAME CLUSTERING_FACTOR
------------------------------ ------------------------------ -----------------
IDX_T4_01 T4 999539
【composite indexes 的 clustering_factor差別小】
doudou@TEST> select count(*) from t3 where x=1 and y=765571731;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 30972477
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | INDEX RANGE SCAN| IDX_T3_01 | 1 | 26 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("X"=1 AND "Y"=765571731)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
67 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t4 where x=1 and y=765571731;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 2556691066
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | INDEX RANGE SCAN| IDX_T4_01 | 1 | 26 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("Y"=765571731 AND "X"=1)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
76 consistent gets
2 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t3 where x=1 and y>0;
COUNT(*)
----------
50037
Execution Plan
----------------------------------------------------------
Plan hash value: 30972477
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 58 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | INDEX RANGE SCAN| IDX_T3_01 | 15446 | 392K| 58 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("X"=1 AND "Y">0 AND "Y" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
220 consistent gets
148 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t4 where x=1 and y>0;
COUNT(*)
----------
50037
Execution Plan
----------------------------------------------------------
Plan hash value: 405148644
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 26 | 481 (1)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 26 | | |
|* 2 | TABLE ACCESS FULL| T4 | 34100 | 865K| 481 (1)| 00:00:06 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("X"=1 AND "Y">0)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
28 recursive calls
0 db block gets
2215 consistent gets
0 physical reads
0 redo size
413 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
doudou@TEST> select count(*) from t3 where y=765571731;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 463314188
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 470 (1)| 00:00:06 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | TABLE ACCESS FULL| T3 | 23 | 299 | 470 (1)| 00:00:06 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("Y"=765571731)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
2201 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
doudou@TEST> select count(*) from t4 where y=765571731;
COUNT(*)
----------
1
Execution Plan
----------------------------------------------------------
Plan hash value: 2556691066
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 13 | 3 (0)| 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 13 | | |
|* 2 | INDEX RANGE SCAN| IDX_T4_01 | 1 | 13 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("Y"=765571731)
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
9 recursive calls
0 db block gets
76 consistent gets
0 physical reads
0 redo size
411 bytes sent via SQL*Net to client
400 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
<!--[if !supportLists]-->1 <!--[endif]-->rows processed
【選擇度高低對composite indexes影響很小】
總結:
1、 前導列是否有序對clustering_factor影響大。前導列有序的composite indexes , clustering_factor 低(效能高)。【反之則效能低】
2、 前導列選擇度高低對clustering_factor影響小。進而對composite indexes影響小。
3、 Clustering_factor高低對 index range scan : ①等值查詢影響小 ②< and >影響大。
建議:
Composite indexes 前導列最好是有序的,這樣clustering_factor低,效能會高。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26442936/viewspace-751497/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Choosing Composite IndexesIndex
- Partitioned Indexes on Composite PartitionsIndex
- Composite Indexes (196)Index
- 高效的SQL(bitmap indexes optimize low cardinality columns)SQLIndex
- 符合資料庫需求的最佳SQL Server版本選擇資料庫SQLServer
- Java列舉:為什麼它是單例模式的最佳選擇?Java單例模式
- 複合索引中前導列對sql查詢的影響索引SQL
- 編寫高效的 CSS 選擇器CSS
- 高效的SQL(Function-based Indexes 函式、運算優化思路)SQLFunctionIndex函式優化
- DBA的最佳選擇—圖形介面還是T-SQL命令? (轉)SQL
- SQL 選擇SQL
- 編寫高效 SQL 語句的最佳實踐SQL
- date列統計資訊陳舊導致sql沒有選擇最優執行計劃SQL
- ubuntu系統怎麼選擇最佳伺服器?ubuntu系統選擇最佳伺服器的教程Ubuntu伺服器
- 陣列選擇排序陣列排序
- 組合索引的前導列與查詢——ORACLE索引Oracle
- 值得收藏!選擇正確BI工具的最佳指南
- 程式設計師跳槽的最佳時機選擇程式設計師
- 分散式 PostgreSQL 叢集(Citus),分散式表中的分佈列選擇最佳實踐分散式SQL
- 【TUNE_ORACLE】檢視每個列的選擇性和基數SQL參考OracleSQL
- Sql Server 參考:char與varchar的選擇SQLServer
- jQuery 選擇器彙總-思維導圖-選擇器jQuery
- 【TUNE_ORACLE】列出可以建立組合索引的SQL(回表再過濾選擇性高的列)的SQL參考Oracle索引SQL
- SQL vs NoSQL:如何選擇?SQL
- 高效的SQL(隱式轉換導致不走索引)SQL索引
- 為啥Underlay才是容器網路的最佳落地選擇
- 網站最佳化中的主機選擇策略網站
- 什麼是index的leading column(索引的前導列)?Index索引
- 翻譯(九)——Clustered Indexes: Stairway to SQL Server Indexes Level 3IndexAISQLServer
- 講解SQL Server的版本區別及選擇SQLServer
- 詳解SQL Server的版本區別及選擇SQLServer
- 最佳實踐|如何寫出簡單高效的 Flink SQL?SQL
- Sql最佳化(十四)分散式環境中的最佳化(2)選擇合適的驅動節點(driving site hint)SQL分散式
- 從效能的角度談SQL Server聚集索引鍵的選擇SQLServer索引
- 演算法金 | 選擇最佳機器學習模型的 10 步指南演算法機器學習模型
- 如何從效能角度選擇陣列的遍歷方式陣列
- 如何選擇高效率的網路安全技術團隊?
- Spark SQL如何選擇join策略SparkSQL