假設我們有以下問題:爲什麼優化程序計劃與實驗性查詢運行不相關?
給定一個表有一列
'X'
,含有某些行隨機 整數從1到100:CREATE TABLE xtable(x) AS SELECT ceil(dbms_random.value * 100) FROM dual CONNECT BY level <= 1000000;
我們必須刪除重複所以所有不同的整數都保留在表中。
讓我們考慮三種解決方案(平均執行時間和優化計劃)之下。
我必須補充,實驗表明:
- 溶液1和2是可伸縮的,並具有與每個行量步驟(附表測試高達10萬行)
- 溶液3具有線性時間的增長指數時間增長大約像
3 * exp(0.6 * N)
我們看到,對於解決方案2優化計劃給無關的實驗結果的期望, 的甚至相反的對他們說:
- 成本和其他值都幾乎是在計劃2相同,3
- 執行時間實際上是解決辦法1相同,2
而且在這個實驗表 的收集統計信息的存在與否不會影響優化程序計劃和執行時間。
請解釋爲什麼我不能在案件2
是什麼原因導致的優化忽略線性和指數的複雜性之間的明顯差異信任優化計劃?
解決方案:
1.
DELETE xtable WHERE rowid IN (
SELECT ri from (
SELECT rowid AS ri,
row_number() OVER(PARTITION BY x ORDER BY null) AS rn
FROM xtable
)
WHERE rn > 1
)
Exe time: 14 - 16 secs
Plan:
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 1000000 | 15000000 | 5119 | 00:00:01 |
| 1 | DELETE | XTABLE | | | | |
| * 2 | HASH JOIN SEMI | | 1000000 | 15000000 | 5119 | 00:00:01 |
| 3 | TABLE ACCESS FULL | XTABLE | 1000000 | 3000000 | 280 | 00:00:01 |
| 4 | VIEW | VW_NSO_1 | 1000000 | 12000000 | 2976 | 00:00:01 |
| * 5 | VIEW | | 1000000 | 25000000 | 2976 | 00:00:01 |
| 6 | WINDOW SORT | | 1000000 | 3000000 | 2976 | 00:00:01 |
| 7 | TABLE ACCESS FULL | XTABLE | 1000000 | 3000000 | 280 | 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - access(ROWID="RI")
* 5 - filter("RN">1)
2.
DELETE xtable WHERE (x, rowid) NOT IN (SELECT x, min(rowid) FROM xtable GROUP BY x)
Exe time: 15 - 17 secs
Plan:
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
--------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 50000 | 150000 | 278162850 | 03:01:06 |
| 1 | DELETE | XTABLE | | | | |
| 2 | FILTER | | | | | |
| 3 | TABLE ACCESS FULL | XTABLE | 1000000 | 3000000 | 281 | 00:00:01 |
| 4 | FILTER | | | | | |
| 5 | SORT GROUP BY NOSORT | | 1000000 | 3000000 | 280 | 00:00:01 |
| 6 | TABLE ACCESS FULL | XTABLE | 1000000 | 3000000 | 280 | 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 5 - access(INTERNAL_FUNCTION("X")=INTERNAL_FUNCTION("X") AND INTERNAL_FUNCTION(ROWID)=INTERNAL_FUNCTION("MIN(ROWID)"))
* 5 - filter(INTERNAL_FUNCTION(ROWID)=INTERNAL_FUNCTION("MIN(ROWID)") AND INTERNAL_FUNCTION("X")=INTERNAL_FUNCTION("X"))
3。
DELETE xtable a WHERE EXISTS(select 1 FROM xtable b WHERE a.x = b.x AND a.rowid < b.rowid)
Exe time: 970 - 990 sec
Plan:
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------------------------
| 0 | DELETE STATEMENT | | 50000 | 300000 | 278208956 | 03:01:08 |
| 1 | DELETE | XTABLE | | | | |
| * 2 | FILTER | | | | | |
| 3 | NESTED LOOPS SEMI | | 50000 | 300000 | 278208956 | 03:01:08 |
| 4 | TABLE ACCESS FULL | XTABLE | 1000000 | 3000000 | 280 | 00:00:01 |
| * 5 | TABLE ACCESS BY ROWID RANGE | XTABLE | 50000 | 150000 | 278 | 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - filter(:VAR2=:VAR1)
* 5 - access("B".ROWID>"A".ROWID)
計劃被上Oracle 12.1.0.2.0
當你說「不能信任案例2中的優化器計劃」時,你是什麼意思?你認爲2和3的執行計劃是相似的嗎?執行計劃3有兩個嵌套循環半連接的全表掃描,然後進行過濾。執行計劃2排序後跟一個過濾器,然後用它來過濾全表掃描的結果。這與第一個執行計劃IMHO更相似。 – Boneist
@Boneist,我認爲列的行,字節,成本,時間的總值的相似性。令人驚訝的是它們幾乎相同,並且當我們用不同數量的行填充表時發生同步變化:1000,10 000,...,10 000 000 – diziaq
加上一個好的準備好Q.請提供Oracle版本並添加*謂詞信息*給解釋計劃。見[這裏](http://stackoverflow.com/questions/34975406/how-to-describe-performance-issue-in-relational-database?answertab=active#tab-top)如何獲取信息。 –