oracle 索引升降序及排序條件 對查詢計劃的影響
建立一個常規的堆表,並在上面建一個複合索引
SQL> create table t1 as select * from all_objects;
表已建立。
SQL> create index idx_t1_1 on t1(owner,object_type);
索引已建立。
下面這個查詢語句比較特殊,
order by的條件與select的列表欄位都在符合索引內,
所以這個查詢的檢索根本沒有涉及到堆表,而完全在索引內完成。
而且因為索引本身就是依序儲存的,所以查詢計劃中並沒有sort這一項。
SQL> set autotrace traceonly explain;
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type;
執行計劃
----------------------------------------------------------
Plan hash value: 2370119825
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| 17 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T1_1 | 4835 | 132K| 17 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL AND "OWNER">='T' AND
"OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
下面的查詢也類似,雖然排序條件中指定使用降序,但是db需要做的只是反向掃描索引。
所以仍然沒有sort的步驟
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner desc,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 2755489192
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| 17 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN DESCENDING| IDX_T1_1 | 4835 | 132K| 17 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL AND "OWNER">='T' AND "OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
可以看出,下面的查詢使查詢計劃多出了一個sort的步驟。
這是因為,雖然order by和select列表的欄位都在索引內,且資料也只會在索引儲存內取得,
但是因為索引都是依升序排列的,所以在取得資料後,db還是要針對第二個欄位進行排序。
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 1804762688
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| | 60 (4)| 00:00:01 |
| 1 | SORT ORDER BY | | 4835 | 132K| 360K| 60 (4)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| IDX_T1_1 | 4835 | 132K| | 17 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement
接下來建立一個相同的堆表,但是建複合索引時指定第二個欄位為降序
SQL> create table t2 as select * from all_objects;
表已建立。
SQL> create index idx_t2_1 on t2(owner,object_type desc);
索引已建立。
執行以下查詢,會發現,因為索引定義時指定第二個欄位為降序,該語句的執行計劃沒有sort這一步驟。
SQL> select owner,object_type from t2
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 2241212547
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1004 | 28112 | 5 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T2_1 | 1004 | 28112 | 5 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("OBJECT_TYPE")) IS NOT
NULL AND "OWNER">='T' AND "OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
但是當order by條件變為全部為升序時,sort的步驟再次出現。
SQL> select owner,object_type from t2
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type;
執行計劃
----------------------------------------------------------
Plan hash value: 3901850472
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1004 | 28112 | 6 (17)| 00:00:01 |
| 1 | SORT ORDER BY | | 1004 | 28112 | 6 (17)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| IDX_T2_1 | 1004 | 28112 | 5 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER">='T' AND "OWNER"<='Z')
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("OBJECT_TYPE")) IS NOT
NULL)
Note
-----
- dynamic sampling used for this statement
SQL> spool off
以上是一個簡單的例子。當表變得比較大時,一個排序的任務可能會佔用較多的資源和時間。
當遭遇效能問題時,有時可以嘗試結合複合索引及排序條件看有沒有改善空間。
SQL> create table t1 as select * from all_objects;
表已建立。
SQL> create index idx_t1_1 on t1(owner,object_type);
索引已建立。
下面這個查詢語句比較特殊,
order by的條件與select的列表欄位都在符合索引內,
所以這個查詢的檢索根本沒有涉及到堆表,而完全在索引內完成。
而且因為索引本身就是依序儲存的,所以查詢計劃中並沒有sort這一項。
SQL> set autotrace traceonly explain;
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type;
執行計劃
----------------------------------------------------------
Plan hash value: 2370119825
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| 17 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T1_1 | 4835 | 132K| 17 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL AND "OWNER">='T' AND
"OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
下面的查詢也類似,雖然排序條件中指定使用降序,但是db需要做的只是反向掃描索引。
所以仍然沒有sort的步驟
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner desc,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 2755489192
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| 17 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN DESCENDING| IDX_T1_1 | 4835 | 132K| 17 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL AND "OWNER">='T' AND "OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
可以看出,下面的查詢使查詢計劃多出了一個sort的步驟。
這是因為,雖然order by和select列表的欄位都在索引內,且資料也只會在索引儲存內取得,
但是因為索引都是依升序排列的,所以在取得資料後,db還是要針對第二個欄位進行排序。
SQL> select owner,object_type from t1
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 1804762688
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4835 | 132K| | 60 (4)| 00:00:01 |
| 1 | SORT ORDER BY | | 4835 | 132K| 360K| 60 (4)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| IDX_T1_1 | 4835 | 132K| | 17 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER">='T' AND "OWNER"<='Z')
filter("OBJECT_TYPE" IS NOT NULL)
Note
-----
- dynamic sampling used for this statement
接下來建立一個相同的堆表,但是建複合索引時指定第二個欄位為降序
SQL> create table t2 as select * from all_objects;
表已建立。
SQL> create index idx_t2_1 on t2(owner,object_type desc);
索引已建立。
執行以下查詢,會發現,因為索引定義時指定第二個欄位為降序,該語句的執行計劃沒有sort這一步驟。
SQL> select owner,object_type from t2
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type desc;
執行計劃
----------------------------------------------------------
Plan hash value: 2241212547
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1004 | 28112 | 5 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_T2_1 | 1004 | 28112 | 5 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("OWNER">='T' AND "OWNER"<='Z')
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("OBJECT_TYPE")) IS NOT
NULL AND "OWNER">='T' AND "OWNER"<='Z')
Note
-----
- dynamic sampling used for this statement
但是當order by條件變為全部為升序時,sort的步驟再次出現。
SQL> select owner,object_type from t2
2 where owner between 'T' and 'Z'
3 and object_type is not null
4 order by owner,object_type;
執行計劃
----------------------------------------------------------
Plan hash value: 3901850472
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1004 | 28112 | 6 (17)| 00:00:01 |
| 1 | SORT ORDER BY | | 1004 | 28112 | 6 (17)| 00:00:01 |
|* 2 | INDEX RANGE SCAN| IDX_T2_1 | 1004 | 28112 | 5 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER">='T' AND "OWNER"<='Z')
filter(SYS_OP_UNDESCEND(SYS_OP_DESCEND("OBJECT_TYPE")) IS NOT
NULL)
Note
-----
- dynamic sampling used for this statement
SQL> spool off
以上是一個簡單的例子。當表變得比較大時,一個排序的任務可能會佔用較多的資源和時間。
當遭遇效能問題時,有時可以嘗試結合複合索引及排序條件看有沒有改善空間。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11411056/viewspace-733375/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- jQuery 條件搜尋查詢 實時取值 升降序排序jQuery排序
- Linq查詢之多個排序條件排序
- 資料庫聚簇索引——not null條件對唯一鍵索引成為聚簇索引的影響資料庫索引Null
- oracle點陣圖索引對DML操作的影響Oracle索引
- ORACLE 查詢條件出現關鍵字:&Oracle
- 磁碟排序對Oracle資料庫效能的影響PT排序Oracle資料庫
- MySQL:查詢欄位數量多少對查詢效率的影響MySql
- MySQL實驗: 實踐索引對全列匹配、最左字首匹配、範圍查詢等條件的影響以及瞭解髒讀、幻讀等MySql索引
- 影響Oracle標量子查詢效能的三個因素Oracle
- Oracle優化案例-統計資訊對執行計劃的影響(十三)Oracle優化
- 【效能】Oracle表並行對邏輯遷移後查詢效能的影響Oracle並行
- mysql條件查詢MySql
- MongoDB查詢條件MongoDB
- 【CURSOR】Oracle繫結變數、執行計劃對遊標的影響Oracle變數
- cluster factor對執行計劃的影響
- Oracle OCP(02):條件和排序Oracle排序
- SpringBoot整合Jpa對資料進行排序、分頁、條件查詢和過濾Spring Boot排序
- Laravel 多條件查詢Laravel
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- Oracle多列統計資訊與直方圖對有關聯多列查詢影響Oracle直方圖
- dex最佳化對Arouter查詢路徑的影響
- Postgresql MVCC架構對從庫長查詢的影響SQLMVC架構
- 使用SSH完成條件及分頁查詢的主要程式碼
- Javaweb-DQL-條件查詢JavaWeb
- 查詢條件封裝物件封裝物件
- AntDesignBlazor示例——列表查詢條件Blazor
- SpringBoot Jpa多條件查詢Spring Boot
- mongodb條件查詢不等於MongoDB
- golang beego orm 查詢條件 or andGolangORM
- 【mybatis-plus】條件查詢MyBatis
- 34. 過濾條件、多表查詢、子查詢
- 20240719資料庫關聯查詢、條件查詢資料庫
- 對GPDB查詢計劃的Motion結點的理解
- hyperf關聯模型條件查詢模型
- 菜品條件分頁查詢
- mysql拆分字串做條件查詢MySql字串
- Linq兩個from查詢條件
- mysql like查詢 - 根據多個條件的模糊匹配查詢MySql
- SQL-基礎語法 - 條件查詢 - 模糊查詢SQL