1. 程式人生 > 其它 >一個關於執行計劃的小問題測試(r8筆記第60天)

一個關於執行計劃的小問題測試(r8筆記第60天)

最近有朋友在微信公眾號後臺留言提了一個問題,問題如下: 執行計劃中,並列的兩條操作比如並列的兩條table access full,上層沒有關聯操作比如hash join,這是什麼意思?

但是兩張表在sql中是有等值連線的,為什麼執行計劃沒有提現連線方式呢? 然後他過了一會附了一張操作截圖。

這個問題一下子看起來就比較清晰了。

為了簡單復現這個問題,在本地做了一個小測試。 為了達到同樣的表結構,我建立了同樣的表。 create table by_fs as select object_id zd_fs, object_name kecheng from all_objects where rownum<11; create table xs_xf as select object_id zd_fs, object_name kecheng from all_objects where rownum<20; 然後啟用trace,得到的執行計劃情況如下:

可以看到是可以復現這個朋友的問題的。這個時候從執行計劃來入手,看到對於表XS_XF走了全表掃描,對於其中的資料在表BY_FS中通過全表掃描進行匹配。 整個執行計劃的關鍵可以看到謂詞資訊: Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("CC"."KECHENG"=:B1) 在by_fs中,會把外層xs_xf的查詢結果通過繫結變數的方式傳入,感覺其實和表關聯的方式應該是一樣的情況。 而如果改為表連線的場景,可以輕鬆實現。改寫為下面的形式繼續檢視。

這個時候可以看到對這兩個表還是走了全表掃描,表連線為hash join的方式,可以看到一致性讀也確實低了不少。 這個地方為什麼看到的是hash join,還是通過謂詞資訊來看。 Predicate Information (identified by operation id): --------------------------------------------------- 1 - access("CC"."KECHENG"="AA"."KECHENG") 目前兩個表還是沒有任何索引的,但是通過謂詞資訊可以看到access的字樣,可見是在資料庫內部做了這一層的對映,把兩個表的資料通過hash演算法進行對映。 我們接著建立索引。 create index ind_xs_xf on xs_xf(kecheng); create index ind_by_fs on by_fs(kecheng);

還是使用最開始的sq

可以看到CBO還是做了很合理的選擇,對於xs_xf還是使用全表掃描,對於返回的結果集,是通過繫結變數的方式傳入子查詢。 我們更近一步,來看看修改為表關聯的方式,執行計劃的變化。

這種結果就好比下面的形式。 select kecheng,zd_fs from by_fs order by kecheng; select * from xs_xf order by kecheng; 針對本例,是對by_fs做了全表掃描,對資料進行了排序,然後根據kecheng對結果集進行了匹配和關聯,最後把結果集輸出。 因為merge-sort join確實使用情況會相對比較少,在資料庫中是存在一個隱含引數來控制的。 NAME VALUE ISDEFAULT ISMOD ISADJ ------------------------------------------ --------- ---------- ----- _optimizer_sortmerge_join_enabled TRUE TRUE FALSE FALSE 當然也可以通過Hint /*+use_merge(cc,aa)來進行控制和管理。 當然更多的資訊沒有進行挖掘,不過從我的直觀感受來看,第一個查詢的效果和表關聯的場景還是很類似的。而且通過CBO來做出的最終判定來看,差別很明顯,但是效果基本是一致的。