【效能優化】執行計劃與直方圖
在Oracle中直方圖是一種對資料分佈質量情況進行描述的工具。它會按照某一列不同值出現數量多少,以及出現的頻率高低來繪製資料的分佈情況,以便能夠指導優化器根據資料的分佈做出正確的選擇。在某些情況下,表的列中的數值分佈將會影響優化器使用索引還是執行全表掃描的決策。當 where 子句的值具有不成比例數量的數值時,將出現這種情況,使得全表掃描比索引訪問的成本更低。這種情況下如果where 子句的過濾謂詞列之上上有一個合理的正確的直方圖,將會對優化器做出正確的選擇發揮巨大的作用,使得SQL語句執行成本最低從而提升效能。
根據dba_objects建立一個傾斜列的表。並在嚴重傾斜的列上建立索引
YANG@yangdb-rac3> create table bind as select * from dba_objects;
Table created.
YANG@yangdb-rac3> update bind set status='INVALID' WHERE WNER='SCOTT';
6 rows updated.
YANG@yangdb-rac3> create index bind_idx on bind(status);
Index created.
收集表和索引的資訊。
YANG@yangdb-rac3> exec dbms_stats.gather_table_stats(user,'BIND',cascade=>true);
PL/SQL procedure successfully completed.
YANG@yangdb-rac3> set autot trace exp
檢視其執行計劃,發現執行計劃並沒有走索引而是全表掃描
YANG@yangdb-rac3> select owner from bind where status='INVALID';
Execution Plan
----------------------------------------------------------
Plan hash value: 3586145581
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36374 | 461K| 291 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| BIND | 36374 | 461K| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("STATUS"='INVALID')
為索引列的兩個值建立直方圖。
YANG@yangdb-rac3> EXEC DBMS_STATS.GATHER_TABLE_STATS(user,'BIND',method_opt => 'FOR ALL INDEXED COLUMNS SIZE 2');
PL/SQL procedure successfully completed.
YANG@yangdb-rac3> select owner from bind where status='INVALID';
Execution Plan
----------------------------------------------------------
Plan hash value: 4106465825
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13 | 169 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| BIND | 13 | 169 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | BIND_IDX | 13 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("STATUS"='INVALID')
但是當對於收集直方圖的列在sql 語句where 中使用繫結變數的時候:執行計劃改變了!沒有選擇索引而是全表掃描。
YANG@yangdb-rac3> variable val varchar2(10);
YANG@yangdb-rac3> exec :val :='VALID';
PL/SQL procedure successfully completed.
YANG@yangdb-rac3> select owner from bind where status= :val;
Execution Plan
----------------------------------------------------------
Plan hash value: 3586145581
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36374 | 461K| 291 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| BIND | 36374 | 461K| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("STATUS"=:VAL)
YANG@yangdb-rac3> exec :val :='INVALID';
PL/SQL procedure successfully completed.
YANG@yangdb-rac3>
YANG@yangdb-rac3> select owner from bind where status= :val;
Execution Plan
----------------------------------------------------------
Plan hash value: 3586145581
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36374 | 461K| 291 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| BIND | 36374 | 461K| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
--------------------------------------------------
1 - filter("STATUS"=:VAL)
YANG@yangdb-rac3> alter system flush shared_pool;
System altered.
避免bind 變數,第一次執行時使用 INVALID
YANG@yangdb-rac3> variable val varchar2(10);
YANG@yangdb-rac3> exec :val :='INVALID';
PL/SQL procedure successfully completed.
YANG@yangdb-rac3> select owner from bind where status= :val;
Execution Plan
----------------------------------------------------------
Plan hash value: 3586145581
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 36374 | 461K| 291 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| BIND | 36374 | 461K| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("STATUS"=:VAL)
YANG@yangdb-rac3> select owner from bind where status= 'INVALID';
Execution Plan
----------------------------------------------------------
Plan hash value: 4106465825
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13 | 169 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| BIND | 13 | 169 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | BIND_IDX | 13 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("STATUS"='INVALID')
其實直方圖具有一下幾個使用限制
1 all predicates on the column use bind variables
2 the column data is uniformly distributed
3 the column is not used in WHERE clauses of queries
4 the column is unique and is used only with equality predicates
當sql 語句遇到上述情況,收集直方圖資訊是無效的。
參考文章:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-709190/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分析執行計劃優化SQLORACLE的執行計劃(轉)優化SQLOracle
- 柱狀圖與執行計劃
- Java 執行緒與同步的效能優化Java執行緒優化
- 直方圖均衡化原理與實現直方圖
- 直方圖均衡化直方圖
- OpenCV計算機視覺學習(9)——影像直方圖 & 直方圖均衡化OpenCV計算機視覺直方圖
- 【MySQL】MySQL的執行計劃及索引優化MySql索引優化
- MySQL 5.7 優化不能只看執行計劃MySql優化
- Oracle資料遷移後由列的直方圖統計資訊引起的執行計劃異常Oracle直方圖
- javascript執行緒及與執行緒有關的效能優化JavaScript執行緒優化
- spark sql語句效能最佳化及執行計劃SparkSQL
- sql語句執行順序與效能優化(1)SQL優化
- PostgreSQL執行計劃變化SQL
- MySQL查詢優化之優化器工作流程以及優化的執行計劃生成MySql優化
- 前端效能優化:細說JavaScript的載入與執行前端優化JavaScript
- 前端效能優化 --- css和js的裝載與執行前端優化CSSJS
- Oracle當number型別超過一定長度直方圖限制導致SQL執行計劃錯誤Oracle型別直方圖SQL
- Oracle優化案例-view merge與coe_load_sql_profile固定執行計劃(十五)Oracle優化ViewSQL
- mysql調優之——執行計劃explainMySqlAI
- js程式碼優化 提高執行效能JS優化
- SQL優化案例-從執行計劃定位SQL問題(三)SQL優化
- Oracle優化案例-從執行計劃定位SQL問題(三)Oracle優化SQL
- MySQL優化從執行計劃開始(explain超詳細)MySql優化AI
- OpenCV之影象直方圖均衡化OpenCV直方圖
- Calcite執行計劃最佳化
- 執行計劃-1:獲取執行計劃
- opencv——影像直方圖與反向投影OpenCV直方圖
- [20210205]警惕toad下優化直方圖相關sql語句.txt優化直方圖SQL
- Oracle調優之看懂Oracle執行計劃Oracle
- Cookbook:優化 Vue 元件的執行時效能優化Vue元件
- Oracle優化案例-統計資訊對執行計劃的影響(十三)Oracle優化
- 灰度直方圖均衡化及其實現直方圖
- [20191220]格式化執行計劃.txt
- 前端效能優化 --- 圖片優化前端優化
- [20190111]執行計劃走位與.txt
- TiDB 查詢優化及調優系列(四)查詢執行計劃的調整及優化原理TiDB優化
- 分析執行計劃優化SQLSQL語句處理的過程(轉)優化SQL
- Oracle優化案例-coe_xfr_sql_profile固定執行計劃與刪除profile(二十五)Oracle優化SQL
- Apache ShardingSphere 5.1.0 執行引擎效能優化揭祕Apache優化