原來的sql是這樣的:一共牽涉5張表,表名和 每張表的索引情況如下:
tableindex nameindex infomation
table_item
item_pk
primary key (id)
table_item
item_lm_idx
last_modified asc
table_attr
attr_pk
primary key (id)
table_desc
desc_pk
primary key (id)
table_delay
delay_pk
primary key (id, partition_key)
table_product
product_p_pk
primary key(product_id)
select … from , table_desc , table_product , table_attr , table_delayed
where
(table_item.id = table_desc.id)
and (table_item.product_id = table_product.product_id(+))
and (table_item.id = table_attr.id(+))
and (table_item.id = table_delay.id(+))
and (table_item.last_modified between to_date( :start_time, 『yyyy-mm-dd hh24:mi:ss』 )
and to_date( :end_time , 『yyyy-mm-dd hh24:mi:ss』 )
)order by table_item.last_modified;
使用的db hint 是:
/*+ index(table_item item_lm_idx) use_nl(table_delay) index(table_delay delay_pk) */
sql> explain plan for
select …
sql> @?/rdbms/admin/utlxpls
由於列印格式不同,我就不把執行計畫貼出來了,執**況良好:
所有的表都使用的了索引,index range scan或者index unique scan
執行join的時候使用了nested loops或者nested loops outer
沒有發現sort join和merge join沒有發現table access full –> full table scan
我們發現即使在sql中有order by table_item.last_modified,在sql執行計畫中也沒有出現任何sort有關的資訊,一般在sql中盡量不要使用order by,因為在db server端進行sort是很耗費資源的。但是有乙個例外,就是表中的資料已經排好序的情況下,我們這裡就是這樣的哦情況,執行計畫中沒有sort是因為當從table_item表中以 table_item.last_modified between :start_time and :end_time取資料時,走的是item_lm_idx –>last_modified asc, 所以取出來的資料本身已經按照last_modified 排好序了。
但是我更改過的sql是這樣的:
where table_item.last_modified=:start_time and table_item.id>:last_id order by table_item.id
讓我悲哀的是這條修改過的sql在有些資料庫伺服器上的執行計畫是好的,有些不好。dba給我的解釋是並不是所有的表的統計資訊都是更新過的,於是在那些統計資訊沒有更新的表上的執行計畫很有可能就不對了。不如說這個:
00 select statement
01 merge join outer
02 nested loops outer(將item,product,desc的結果和table_delay進行nested join)
03 merge join(由兩個sort join的結果組成,得到item,product,desc3張表的join結果)
04 sort join(將table_item和table_product的結果按照id進行排序)
05 nested loops outer(將table_item和table_product進行nested outer join)
06 table access by index rowid –> table_item
07 index range scan –> item_lm_idx(使用item_lm_idx索引)
08 table access by index rowid –> table_product
09 index unique scan –> product_p_pk
10 sort join(將table_desc滿足條件的記錄按照id進行排序)
11 table access by index rowid –> table_desc
12 index range scan –> rtable_desc_pk
13 partition range all
14 table access by local index rowid –> table_delay
15 index range scan –> delay_pk
16 sort join
17 table access full –> table_attr
注意到使用了很多merge sort,而處理table_attr的時候更是出現了full table scan,更本就不使用索引。這裡說句老實話,我不知道是不是應該dba更新統計資訊,重新給相關的表更新一下統計資訊,還是就趕緊改一下db hint把自己的事情做完就算。不過我也理解的,ebay的資料庫太大了,不是隨便想做什麼就行的,最後我還是選擇了修改db hint.
ticket resolve的結果是,修改db hint :
/*+
index_asc(table_attr attr_pk)
index(table_item item_lm_idx)
use_nl(table_item table_attr table_desc table_delayed table_product) index(table_delay delay_pk)
index(table_product product_p_pk)
index(table_desc rtable_desc_pk)
*/ 給所有的表都制定index,建議oracle對所有的表都使用nested loops join。重新看一下執行計畫:
00 select statement
01 sort order by
02 nested loops outer
03 nested loops outer
…(以下省略)
可以看到,修改db hint以後,只有對最後的結果進行sort,這也是我們的初衷。沒有sort join和merge join了。速度也快了很多。因為ebay的db是split的,dba為了保險,幫我把這條修改過的sql對該資料庫所有的splits都執行了一次,才把ticket標識成resolved.
我剛把**改了,新增了判斷,如果執行新的sql就使用修改的hint。待會給qa測試,idc的sunil還不肯發bug給我,因為他在qa環境沒有觀察到這個問題,甚至的production standby db也不能重現。這一點只能用樓上dba的話來解釋了:雖然是同乙個db的不同的split,但是不同的splits之間資料還是有差異,統計資料也不同,結果是影響oracle做出判斷,所以他們做sql review的時候都是要執行一下的,而不是光看看執行計畫。
謝謝coc dba team的amao和alex給我上了一課。
mysql首次 mysql 首次安裝及問題解決
2017年9月27日 安裝並配置mysql 安裝路徑為d mysql 5.7.19 winx64 2.生成mysql的配置檔案my.ini 放置路徑為d mysql 5.7.19 winx64 3.my.ini 配置資訊 mysql 設定mysql客戶端預設字符集 default character...
首次接觸DirectDraw
directdraw 1.directdraw可能是directx中最重要的技術,因為它溝通了2d圖形的顯示和direct3d所依賴的真緩衝層。只要掌握了directdraw,就能夠編寫各種在dos16 32下編寫的圖形應用程式。directdraw是理解directx中許多概念的關鍵,所以要特別注...
GDrive首次現身!
還記得gdrive麼?自從它第一次出現在google的洩露文件上,它就成為了世界關注的焦點。根據傳言,gdrive將會是google要推出的網路儲存服務,類似於網路硬碟,但它的容量是無限的。在這個訊息洩露後,google馬上把相關的文件給刪除了,這反而令人覺得gdrive並非只是謠言。隨後微軟自己也...