oracle最佳化sql的內部過程
Oracle對sql的最佳化過程如下
本文只關注查詢重寫和查詢最佳化
查詢重寫
獨立於最佳化器 ,分兩部分
1 子查詢展開
分為相關子查詢和非相關子查詢,將其轉化為等價join;
Hint:unnest/no_unnest/hash_sj/hash_aj
通常子查詢在最後執行,透過Push_subq可儘早執行http://blog.itpub.net/15480802/viewspace-688364/
參考案例
http://blog.itpub.net/15480802/viewspace-703260/
http://blog.itpub.net/15480802/viewspace-688361/
2 檢視合併
或將檢視展開,或把外部條件推入檢視;不能合併的檢視,執行計劃會顯示View關鍵字;
Hint: merge/no_merge
限制條件
1 集合操作 union/intersect/minus/union all
2 connect by
3 rownum
查詢最佳化
1 In-list/OR
最佳化器有3種處理方法
1 IN-list迭代器:
將row source每一行同IN-list值逐一比較,列必須有索引;10157事件可禁用此功能;
2 IN-list擴充套件:
將IN-list或OR擴充套件成UNION ALL;CBO必須對每個擴充套件子句評估cost,且執行時每個分支都要讀一次表,可使用NO_EXPAND禁用(與USE_CONCAT相反),或將IN-list值存入lookup表並join改進;
3 Filter過濾:
採用filter對取出的結果集進行過濾;
案例
DB:11203
create table temp as select object_id,object_name,status,owner from dba_objects;
exec dbms_stats.gather_table_stats('SYS','TEMP');
select object_name,status from temp where object_id in (1,2,3);
1 filter
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1896031711
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 108 | 188 (2)| 00:00:03 |
|* 1 | TABLE ACCESS FULL| TEMP | 3 | 108 | 188 (2)| 00:00:03 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"=1 OR "OBJECT_ID"=2 OR "OBJECT_ID"=3)
13 rows selected.
2 OR展開
use_concat在11203已經不好使了,需要改為USE_CONCAT( OR_PREDICATES(1) )
select /*+ use_concat */ object_name,status from temp where object_id in (1,2,3); --依舊使用filter
select /*+ USE_CONCAT( OR_PREDICATES(1) ) */ object_name,status from temp where object_id in (1,2,3)--與下面的union all等價
select object_name,status from temp where object_id =1
union all
select object_name,status from temp where object_id =2
union all
select object_name,status from temp where object_id =3;
--使用USE_CONCAT(OR_PREDICATES(1))
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 108 | 562 (1)| 00:00:07 |
| 1 | CONCATENATION | | | | | |
|* 2 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
|* 3 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
|* 4 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_ID"=1)
3 - filter("OBJECT_ID"=2)
4 - filter("OBJECT_ID"=3)
--直接使用union all
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 108 | 562 (67)| 00:00:07 |
| 1 | UNION-ALL | | | | | |
|* 2 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
|* 3 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
|* 4 | TABLE ACCESS FULL| TEMP | 1 | 36 | 187 (1)| 00:00:03 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("OBJECT_ID"=1)
3 - filter("OBJECT_ID"=2)
4 - filter("OBJECT_ID"=3)
3 IN-list遍歷
要先建立索引
create index ind1 on temp(object_id);
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 108 | 5 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEMP | 3 | 108 | 5 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | IND1 | 3 | | 4 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("OBJECT_ID"=1 OR "OBJECT_ID"=2 OR "OBJECT_ID"=3)
2 星型轉換
適用於事實表很小,維度表很大且缺失連線條件
容易忽略的Hint
PUSH_SUBQ
This hint causes subqueries to be evaluated at the earliest possible time in a query block. Subqueries are typically executed as the last operation.
PUSH_PRED and NO_PUSH_PRED
These two hints, respectively, force and prevent join predicates from being pushed into a view.
DRIVING_SITE
指定執行計劃在remote還是local,driving_site(local)/driving_site(remote)分別指定執行於local/remote db;
This hint is useful when the local tables are small, a lot of data must be processed at the remote site, and only a small subset of the data (for example, aggregated with
GROUP BY, MIN, MAX) is returned to the originating node. In such cases, it makes sense to use the remote site as the driving site by shipping the small local tables across
for processing.
INDEX_COMBINE
If no indexes are given as arguments for the INDEX_COMBINE hint, the optimizer will use whatever Boolean combination of indexes has the best cost estimate. If
certain indexes are given as arguments, the optimizer will try to use some Boolean combination of those particular indexes. Because the Oracle server can convert ROWIDs to bitmaps, the indexes in the bitmap tree do not have to be bitmap indexes; they can be regular B*-tree indexes as well.
INDEX_JOIN
This hint explicitly instructs the optimizer to use an index join as an access path. For the hint to have a positive effect, there must exist a sufficiently small number of
indexes that contain all the columns required to resolve the query.
AND_EQUAL
Choose an access path that merges the scans on several single-column indexes. The maximum number of indexes that can be merged is five.
PQ_DISTRIBUTE http://blog.itpub.net/15480802/viewspace-741125/
This hint improves the performance of parallel join operations. You can specify how rows of joined tables should be distributed among producer and consumer query
servers. Using this hint overrides decisions the optimizer would normally make. The second and third arguments specify the distribution for the inner and the outer table,
respectively
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-2148909/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【SQL】Oracle避免動態SQL,提高過程執行效率SQLOracle
- Oracle資料庫SQL語句執行過程Oracle資料庫SQL
- golang gc的內部最佳化GolangGC
- Ms Sql Server查詢儲存過程中的內容SQLServer儲存過程
- oracle SQL最佳化器SQL Tuning Advisor (STA)OracleSQL
- oracle的儲存過程Oracle儲存過程
- 關於關聯查詢sql的一次最佳化過程及其他SQL
- oracle索引核心過程Oracle索引
- Oracle儲存過程Oracle儲存過程
- 一條Sql的執行過程SQL
- Sqlsugar呼叫Oracle的儲存過程SqlSugarOracle儲存過程
- 【REDO】Oracle redo內部結構Oracle Redo
- sql server 2005 資料修改的內部原理SQLServer
- 揭秘計算機指令執行的神秘過程:CPU內部的絕密操作計算機
- Oracle某行系統SQL最佳化(案例四)OracleSQL
- SQL隱碼攻擊的詳細過程!網路安全學習內容SQL
- oracle邏輯讀過程Oracle
- Oracle儲存過程-1Oracle儲存過程
- Oracle - 執行過的SQL、正在執行的SQL、消耗資源最多的SQLOracleSQL
- Spark SQL / Catalyst 內部原理 與 RBOSparkSQL
- Pytorch最佳化過程展示:tensorboardPyTorchORB
- 深入解析 oracle drop table內部原理Oracle
- oracle跟蹤常用內部事件號Oracle事件
- openGauss核心:SQL解析過程分析SQL
- SQL 分頁儲存過程SQL儲存過程
- SQL SERVER 學習過程(一)SQLServer
- Oracle某X系統SQL最佳化(案例六)OracleSQL
- 原創:oracle 儲存過程Oracle儲存過程
- Oracle ASM Rebalance執行過程OracleASM
- SQL Server儲存過程的優缺點SQLServer儲存過程
- MySQL 中一條 sql 的執行過程MySql
- 一條sql語句的執行過程SQL
- 一條 sql 的執行過程詳解SQL
- Laravel 列印請求過程中的所有 SQLLaravelSQL
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- 【Oracle】儲存過程中將動態SQL的多行結果進行迴圈遍歷Oracle儲存過程SQL
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- SQL server儲存過程函式SQLServer儲存過程函式
- mysql執行sql語句過程MySql