10.2解決了10.1以下的Transitive Closure變化
如果在關聯列中新增一個額外的預測,10.1版本資料庫transitive Closure在處理SQL語句條件過程中,會剔除掉多餘的預測條件,例如:
where colA =colB
and colA=5
則在Transitive Closure處理過程中,將條件轉化成:
where colA = 5
and colB = 5
而關聯條件colA=colB被剔除。
以上的剔除在CBO計算cardinality的時候,可能造成計算的錯誤。10.2版本將不再把關聯條件剔除,所以其 轉發成:
where colA = colB
and colA=5
and colB=5
以下是具體的實驗:
1、建立測試指令碼
SQL>execute dbms_random.seed(0)
SQL>create table t1
as
select
trunc(dbms_random.value(0, 30 )) join1,
trunc(dbms_random.value(0, 50 )) join2,
lpad(rownum,10) v1,
rpad('x',100) padding
from
all_objects
where
rownum <= 10000;
SQL>create table t2
as
select
trunc(dbms_random.value(0, 40 )) join1,
trunc(dbms_random.value(0, 40 )) join2,
lpad(rownum,10) v1,
rpad('x',100) padding
from
all_objects
where
rownum <= 10000;
2、統計分析(略)
3、10.1.0.2版本進行測試
SQL>set autotrace traceonly explain
SQL>select t1.v1, t2.v1
from
t1, t2
where
t1.join1 = 20
and t2.join1 = t1.join1
and t2.join2 = t1.join2
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1667 | 56678 | 83 (4)| 00:00:02 |
|* 1 | HASH JOIN | | 1667 | 56678 | 83 (4)| 00:00:02 |
|* 2 | TABLE ACCESS FULL | T2 | 250 | 4250 | 41 (3)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 333 | 5661 | 41 (3)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T2"."JOIN2"="T1"."JOIN2")
2 - filter("T2"."JOIN1"=20)
3 - filter("T1"."JOIN1"=20)
從預測資訊中我們看出剔除了t2.join1 = t1.join1的預測,在cardinality的計算也因此發生了偏差, 具體計算如下:
Join Selectivity(ID=3)= ((t1.num_rows - t1.null)/t1.num_rows)/30=1/30
Join cardinality(ID=3)= 10000 * Join Selectivity(ID=3)
= 10000 * 1/30 =333
Join Selectivity(ID=2)= ((t2.num_rows - t2.null)/t1.num_rows)/40=1/40
Join cardinality(ID=2)= 10000 * Join Selectivity(ID=2)
= 10000 * 1/40 =250
Join Selectivity(ID=1)= ((t1.num_rows(join2)- t1.null(join2))/t1.num_rows(join2)) *
((t2.num_rows(join2)- t2.null(join2))/t2.num_rows(join2)) *
1/max(t1.distinct_value(join2), t2.distinct_value(join2)
= 1/max(40,50)=1/50
Join cardinality(ID=1)= Join cardinality(ID=3)* Join cardinality(ID=2)*
Join Selectivity(ID=1)
= 1000/30 * 1000/40 * 1/50
= 1667
在10.2.0.1 測試以上指令碼執行計劃如下:
Execution Plan
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 52 | 1768 | 81 (2)| 00:00:01 |
|* 1 | HASH JOIN | | 52 | 1768 | 81 (2)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | T2 | 250 | 4250 | 40 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 333 | 5661 | 40 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T2"."JOIN1"="T1"."JOIN1" AND "T2"."JOIN2"="T1"."JOIN2")
2 - filter("T2"."JOIN1"=20)
3 - filter("T1"."JOIN1"=20)
我們發現ID=1出現了變化,並沒有剔除 t2.JOIN1=t1.JOIN1,所以CBO計算公式發生瞭如下變化
Join cardinality(ID3)=10000/30
Join cardinality(ID2)=10000/40
Join Selectivity(ID3)=1/max(t1.distinct_value(join1)* t1.distinct_value(join2),
t2.distinct_value(join1)* t2.distinct_value(join2))
= 1/max(1500,1600)=1/1600
Join cardinality(ID3)= 10000/30 * 10000/40 * 1/1600
= 10000/(12*16)
= 10000/192
= 52
所以在10.1版本以下,為了保證CBO能正確計算cardinality,語句需要修改為
SQL>select t1.v1, t2.v1
from
t1, t2
where
t1.join1 = 20
and t2.join1 = t1.join1
and t2.join2 = t1.join2
and t2.join1 = 20;
總之一句話,隨著ORACLE版本升級,CBO計算越來越智慧了。
where colA =colB
and colA=5
則在Transitive Closure處理過程中,將條件轉化成:
where colA = 5
and colB = 5
而關聯條件colA=colB被剔除。
以上的剔除在CBO計算cardinality的時候,可能造成計算的錯誤。10.2版本將不再把關聯條件剔除,所以其 轉發成:
where colA = colB
and colA=5
and colB=5
以下是具體的實驗:
1、建立測試指令碼
SQL>execute dbms_random.seed(0)
SQL>create table t1
as
select
trunc(dbms_random.value(0, 30 )) join1,
trunc(dbms_random.value(0, 50 )) join2,
lpad(rownum,10) v1,
rpad('x',100) padding
from
all_objects
where
rownum <= 10000;
SQL>create table t2
as
select
trunc(dbms_random.value(0, 40 )) join1,
trunc(dbms_random.value(0, 40 )) join2,
lpad(rownum,10) v1,
rpad('x',100) padding
from
all_objects
where
rownum <= 10000;
2、統計分析(略)
3、10.1.0.2版本進行測試
SQL>set autotrace traceonly explain
SQL>select t1.v1, t2.v1
from
t1, t2
where
t1.join1 = 20
and t2.join1 = t1.join1
and t2.join2 = t1.join2
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1667 | 56678 | 83 (4)| 00:00:02 |
|* 1 | HASH JOIN | | 1667 | 56678 | 83 (4)| 00:00:02 |
|* 2 | TABLE ACCESS FULL | T2 | 250 | 4250 | 41 (3)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 333 | 5661 | 41 (3)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T2"."JOIN2"="T1"."JOIN2")
2 - filter("T2"."JOIN1"=20)
3 - filter("T1"."JOIN1"=20)
從預測資訊中我們看出剔除了t2.join1 = t1.join1的預測,在cardinality的計算也因此發生了偏差, 具體計算如下:
Join Selectivity(ID=3)= ((t1.num_rows - t1.null)/t1.num_rows)/30=1/30
Join cardinality(ID=3)= 10000 * Join Selectivity(ID=3)
= 10000 * 1/30 =333
Join Selectivity(ID=2)= ((t2.num_rows - t2.null)/t1.num_rows)/40=1/40
Join cardinality(ID=2)= 10000 * Join Selectivity(ID=2)
= 10000 * 1/40 =250
Join Selectivity(ID=1)= ((t1.num_rows(join2)- t1.null(join2))/t1.num_rows(join2)) *
((t2.num_rows(join2)- t2.null(join2))/t2.num_rows(join2)) *
1/max(t1.distinct_value(join2), t2.distinct_value(join2)
= 1/max(40,50)=1/50
Join cardinality(ID=1)= Join cardinality(ID=3)* Join cardinality(ID=2)*
Join Selectivity(ID=1)
= 1000/30 * 1000/40 * 1/50
= 1667
在10.2.0.1 測試以上指令碼執行計劃如下:
Execution Plan
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 52 | 1768 | 81 (2)| 00:00:01 |
|* 1 | HASH JOIN | | 52 | 1768 | 81 (2)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | T2 | 250 | 4250 | 40 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | T1 | 333 | 5661 | 40 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T2"."JOIN1"="T1"."JOIN1" AND "T2"."JOIN2"="T1"."JOIN2")
2 - filter("T2"."JOIN1"=20)
3 - filter("T1"."JOIN1"=20)
我們發現ID=1出現了變化,並沒有剔除 t2.JOIN1=t1.JOIN1,所以CBO計算公式發生瞭如下變化
Join cardinality(ID3)=10000/30
Join cardinality(ID2)=10000/40
Join Selectivity(ID3)=1/max(t1.distinct_value(join1)* t1.distinct_value(join2),
t2.distinct_value(join1)* t2.distinct_value(join2))
= 1/max(1500,1600)=1/1600
Join cardinality(ID3)= 10000/30 * 10000/40 * 1/1600
= 10000/(12*16)
= 10000/192
= 52
所以在10.1版本以下,為了保證CBO能正確計算cardinality,語句需要修改為
SQL>select t1.v1, t2.v1
from
t1, t2
where
t1.join1 = 20
and t2.join1 = t1.join1
and t2.join2 = t1.join2
and t2.join1 = 20;
總之一句話,隨著ORACLE版本升級,CBO計算越來越智慧了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/354732/viewspace-623136/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- (轉)手工升級資料庫10.1到10.2資料庫
- 10.2 多列關聯cardianlity公式變化公式
- Xcode 10.1 新特性及解決的問題XCode
- javascript中的閉包closure詳解JavaScript
- iOS 10.1測試版來了:相機加入背景虛化iOS
- win10更新完後變卡了怎麼解決 win10系統更新升級後變卡了的解決步驟Win10
- Javascript ClosureJavaScript
- Jbuilder2006中使用1.5以下JDK的解決方法UIJDK
- JavaScript Closure MemorizationJavaScript
- Js closure and bindJS
- 大資料開啟了新的時代變革,數字化智慧經營已成為應對這場變革的最佳解決方案。大資料
- 父DIV的高度不能根據子DIV自動變化的解決
- oracle 10.2 for linux 5.7 netca錯誤解決辦法OracleLinux
- JS中的 閉包(Closure)JS
- JavaScript變數作用域(Variable Scope)和閉包(closure)的基礎知識JavaScript變數
- vue解決IE9及以下不顯示placeholder的問題VueIE9
- OAuth 2.1 帶來了哪些變化OAuth
- QT UI更改編譯後,輸出無變化 解決QTUI編譯
- 解決邏輯匯出後SEQUENCE的值發生變化的問題
- Xcode10.2無法將專案執行到iOS10以下的模擬器上XCodeiOS
- 電腦c盤滿了變成紅色了怎麼清理 c盤已滿的解決辦法
- JS閉包ClosureJS
- PHP 閉包(Closure)PHP
- Javascript閉包(Closure)JavaScript
- JS-閉包(closure)的理解JS
- Lua的function、closure和upvalue(轉)Function
- symantec10.1企業版部分客戶端無法更新 解決方法客戶端
- 解決目錄“中毒變exe”的方法
- win10語音音質變差如何解決_升級win10後電腦音質變差了的解決方法Win10
- 解決了一個PC的問題
- Webpack的理解以及解決了的問題Web
- Android 5.0以下XML定義的drawable不識別?attr/屬性的解決思路AndroidXML
- PHP 的Closure的bind 詳細介紹PHP
- 解決Windows圖示變白Windows
- 在RHEL5.5下安裝Cognos 10.1 缺少 libXm.so.3解決方法
- 調變解調器已刪除的解決辦法
- 本機被dns劫持了的解決方法DNS
- AIGC 真的解決了我的痛點AIGC