[20201224]order by欄位順序與查詢條件為NULL.txt
[20201224]order by欄位順序與查詢條件為NULL.txt
--//在做最佳化遇到的問題,在測試環境做一個分析。
1.環境:
SCOTT@book> @ ver1
PORT_STRING VERSION BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
SCOTT@book> create table t1 as select * from dba_objects ;
Table created.
SCOTT@book> create index i_t1_owner_SUB_NAME_CREATED on t1(owner,SUBOBJECT_NAME,CREATED ) ;
Index created.
2.測試:
SCOTT@book> alter session set statistics_level = all;
Session altered.
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by owner,subobject_name,created) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by subobject_name,created,owner) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by subobject_name,owner,created) where rownum<=5;
--//如果order by欄位順序如上,上面3條語句,執行計劃如下:
Plan hash value: 2602283460
-------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 4 (100)| | 5 |00:00:00.01 | 6 |
|* 1 | COUNT STOPKEY | | 1 | | | | | 5 |00:00:00.01 | 6 |
| 2 | VIEW | | 1 | 5 | 45 | 4 (0)| 00:00:01 | 5 |00:00:00.01 | 6 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 5 | 120 | 4 (0)| 00:00:01 | 5 |00:00:00.01 | 6 |
|* 4 | INDEX RANGE SCAN | I_T1_OWNER_SUB_NAME_CREATED | 1 | 2884 | | 3 (0)| 00:00:01 | 5 |00:00:00.01 | 4 |
-------------------------------------------------------------------------------------------------------------------------------------------------------
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by created,owner,subobject_name) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by created,subobject_name,owner) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYS' and subobject_name is null order by owner,created,subobject_name) where rownum<=5;
--//如果order by欄位順序如上,上面3條語句,執行計劃如下:
--//規律就是subobject_name在created的後面.
Plan hash value: 2513547123
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 102 (100)| | 5 |00:00:00.04 | 1131 | | | |
|* 1 | COUNT STOPKEY | | 1 | | | | | 5 |00:00:00.04 | 1131 | | | |
| 2 | VIEW | | 1 | 2884 | 25956 | 102 (1)| 00:00:02 | 5 |00:00:00.04 | 1131 | | | |
|* 3 | SORT ORDER BY STOPKEY | | 1 | 2884 | 69216 | 102 (1)| 00:00:02 | 5 |00:00:00.04 | 1131 | 2048 | 2048 | 2048 (0)|
| 4 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 2884 | 69216 | 101 (0)| 00:00:02 | 37663 |00:00:00.03 | 1131 | | | |
|* 5 | INDEX RANGE SCAN | I_T1_OWNER_SUB_NAME_CREATED | 1 | 2884 | | 13 (0)| 00:00:01 | 37663 |00:00:00.01 | 129 | | | |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--//這種情況無法利用後面的限制rownum<=5的條件.邏輯讀上升。
--//如果是等值查詢,order by 任何順序都沒有問題.
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by owner,subobject_name,created) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by subobject_name,created,owner) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by subobject_name,owner,created) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by created,owner,subobject_name) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by created,subobject_name,owner) where rownum<=5;
select * from (select last_ddl_time from t1 where owner='SYSTEM' and subobject_name ='P_LESSTHAN100' order by owner,created,subobject_name) where rownum<=5;
Plan hash value: 2602283460
-------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 4 (100)| | 5 |00:00:00.01 | 6 |
|* 1 | COUNT STOPKEY | | 1 | | | | | 5 |00:00:00.01 | 6 |
| 2 | VIEW | | 1 | 5 | 45 | 4 (0)| 00:00:01 | 5 |00:00:00.01 | 6 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 5 | 120 | 4 (0)| 00:00:01 | 5 |00:00:00.01 | 6 |
|* 4 | INDEX RANGE SCAN | I_T1_OWNER_SUB_NAME_CREATED | 1 | 51 | | 3 (0)| 00:00:01 | 5 |00:00:00.01 | 4 |
-------------------------------------------------------------------------------------------------------------------------------------------------------
--//你可以發現order by無論什麼順序,都不影響執行計劃。對比前面主要差異在 subobject_name is null的條件。
--//視乎在等值與is null條件上判斷存在某種不同。
--//當然這些僅僅是細節問題,僅僅引起在工作中注意。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2745167/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- where語句中多條件查詢欄位NULL與NOT NULL不確定性查詢Null
- 順序查詢
- [20170703]11g增加欄位與查詢條件的變化
- 查詢/刪除重複的資料(單個欄位和多個欄位條件)
- odoo 為可編輯列表檢視欄位搜尋新增查詢過濾條件Odoo
- MySQL in 查詢,並通過 FIELD 函式按照查詢條件順序返回結果MySql函式
- Spark SQL解析查詢parquet格式Hive表獲取分割槽欄位和查詢條件SparkSQLHive
- DNS查詢順序DNS
- 查詢作為條件的SQLSQL
- 同一欄位多個查詢條件時遇到的一個問題
- 無合適where條件過濾時儘量選擇order by後的欄位以驅動表進行查詢薦
- connect by與where條件執行順序問題
- DS靜態查詢之順序查詢
- 順序查詢和二分查詢
- 順序表應用6:有序順序表查詢
- MongoDB查詢條件MongoDB
- MongoDB條件查詢MongoDB
- mysql條件查詢MySql
- clob 欄位查詢
- oracle更改欄位名順序的方法Oracle
- mysql 查詢欄位為null或者非nullMySqlNull
- [Mysql 查詢語句]——查詢欄位MySql
- 資料型別為date作為查詢條件資料型別
- CYmysql根據json欄位內容作為查詢條件(包括json陣列)檢索資料dvnMySqlJSON陣列
- 欄位按照指定 ID 順序進行排序排序
- MySQL 查詢處理 SQL查詢執行順序MySql
- Laravel 多條件查詢Laravel
- SQL多條件查詢SQL
- 條件查詢JSPJS
- Oracle 優化器與sql查詢執行順序Oracle優化SQL
- #查詢演算法#【1】簡單查詢:順序、折半查詢演算法
- 查詢條件和條數,先查詢兩條免費的,後面為vip
- 為 MySQL 的查詢結果新增排名欄位MySql
- arcgis欄位值計算(擷取A欄位前8位+按照順序計算8位)
- 改變表的欄位順序dbms_REDEFINITION
- Oracle 最佳化器與sql查詢執行順序OracleSQL
- 模型欄位與序列化正反向查詢模型
- 在 with 查詢中只查詢個別欄位