一個執行計劃解析的小問題分析
前幾天,一個開發的同學讓我幫忙做一個大查詢,給了我一個資料列表,裡面的ID有幾萬個,提供了一個SQL語句,看這情況還得我自己來解析生成相關的SQL了。
假設ID列表為:
T100
T200
T300
SQL語句為:
select peak_transaction_id,cash ,req_time ,back_time from peak_new.peak_detail where peak_transaction_id=?;
對我來說拼成動態SQL也是分分鐘,但是這種方式不推薦,還是推薦使用資料的結果集方式來匹配。
所以我可以根據id拼接成insert語句,或者直接使用外部表來關聯。表裡只有一個欄位id varchar2(30)
在執行語句之前我還是會照例來檢視執行計劃,如果太差我就提前想別的辦法了。
執行計劃著實讓我大跌眼鏡。一個簡單的鍵值關聯的語句,執行計劃竟然如此的查,來看看瓶頸在哪裡。
可以從謂詞資訊看出,裡面做了資料型別的轉換,根據ID這個欄位值資料型別應該是varchar2,是不需要轉換為number型別的。
但是透過執行計劃看出,內部是做了資料型別的轉換,最後這種關聯方式的消耗竟然如此驚人。
我就感覺有些蹊蹺,為什麼會有這種差別,按理來說是不需要這種型別轉換啊。
呼叫的SQL語句如下:
select TEST_transaction_id,cash ,req_time ,back_time from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
發現問題的癥結在於tempdba.test不是我剛剛建立的臨時表,而是指向了一個已經存在的表。這個表的結構如下:
所以這個問題就有點意思了,tempdba.test雖然和屬主下的表test同名,但是欄位完全不同,在生成執行計劃的時候竟然還能成功,這個也讓人著實懷疑最佳化器處理執行計劃是不是也有很多不足之處。
我使用了正確的schema之後,重新生成執行計劃,這一次得到的預估結果還是在接受範圍之內。我完全可以在備庫去跑這個查詢實現目標。
那麼問題來了,是不是執行計劃對於欄位的校驗存在疏漏呢,我們來簡單測試幾個小例子。
發現在常見的表關聯中還是能夠校驗出來的。
再來看看exists的方式是否也有問題。發現也是可以檢測出來的。
所以再回頭看這個問題,就會發現在最開始的語句中。
select TEST_transaction_id,cash ,req_time ,back_time from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
採用in的子查詢的時候,對於子查詢中的列可以和關聯的表不同名,我們可以取別名來達到的相容的目的,我想正是如此在執行計劃中也會弱化了這方面的檢查,嚴格來說,姑且算是一個bug吧。
假設ID列表為:
T100
T200
T300
SQL語句為:
select peak_transaction_id,cash ,req_time ,back_time from peak_new.peak_detail where peak_transaction_id=?;
對我來說拼成動態SQL也是分分鐘,但是這種方式不推薦,還是推薦使用資料的結果集方式來匹配。
所以我可以根據id拼接成insert語句,或者直接使用外部表來關聯。表裡只有一個欄位id varchar2(30)
在執行語句之前我還是會照例來檢視執行計劃,如果太差我就提前想別的辦法了。
執行計劃著實讓我大跌眼鏡。一個簡單的鍵值關聯的語句,執行計劃竟然如此的查,來看看瓶頸在哪裡。
可以從謂詞資訊看出,裡面做了資料型別的轉換,根據ID這個欄位值資料型別應該是varchar2,是不需要轉換為number型別的。
但是透過執行計劃看出,內部是做了資料型別的轉換,最後這種關聯方式的消耗竟然如此驚人。
我就感覺有些蹊蹺,為什麼會有這種差別,按理來說是不需要這種型別轉換啊。
呼叫的SQL語句如下:
select TEST_transaction_id,cash ,req_time ,back_time from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
發現問題的癥結在於tempdba.test不是我剛剛建立的臨時表,而是指向了一個已經存在的表。這個表的結構如下:
所以這個問題就有點意思了,tempdba.test雖然和屬主下的表test同名,但是欄位完全不同,在生成執行計劃的時候竟然還能成功,這個也讓人著實懷疑最佳化器處理執行計劃是不是也有很多不足之處。
我使用了正確的schema之後,重新生成執行計劃,這一次得到的預估結果還是在接受範圍之內。我完全可以在備庫去跑這個查詢實現目標。
那麼問題來了,是不是執行計劃對於欄位的校驗存在疏漏呢,我們來簡單測試幾個小例子。
發現在常見的表關聯中還是能夠校驗出來的。
再來看看exists的方式是否也有問題。發現也是可以檢測出來的。
所以再回頭看這個問題,就會發現在最開始的語句中。
select TEST_transaction_id,cash ,req_time ,back_time from TEST_new.TEST_detail where TEST_transaction_id in (select id from tempdba.test);
採用in的子查詢的時候,對於子查詢中的列可以和關聯的表不同名,我們可以取別名來達到的相容的目的,我想正是如此在執行計劃中也會弱化了這方面的檢查,嚴格來說,姑且算是一個bug吧。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2120633/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分析執行計劃優化SQLORACLE的執行計劃(轉)優化SQLOracle
- 一個“指令碼執行夯死”問題的分析指令碼
- MySQL執行計劃解析MySql
- MySQL執行計劃解析(四)MySql
- explain執行計劃分析AI
- 【YashanDB知識庫】繫結引數,同一個sql多個執行計劃的問題SQL
- SQL執行計劃異常引起的效能問題SQL
- SQL執行計劃異常 引起的效能問題SQL
- SqlServer的執行計劃如何分析?SQLServer
- DB2執行計劃分析DB2
- [20210114]toad檢視真實執行計劃問題.txt
- 執行計劃-5:第一個子操作的變化
- [20210926]並行執行計劃疑問.txt並行
- 執行計劃-1:獲取執行計劃
- mysql 執行計劃索引分析筆記MySql索引筆記
- (4) MySQL中EXPLAIN執行計劃分析MySqlAI
- 檢視一個正在執行的sql的執行計劃(explain for connection processlist_id)SQLAI
- 關於 AppCrawler 執行過程中的幾個小問題APP
- MySQL——通過EXPLAIN分析SQL的執行計劃MySqlAI
- 一個小問題
- SQL優化案例-從執行計劃定位SQL問題(三)SQL優化
- Oracle優化案例-從執行計劃定位SQL問題(三)Oracle優化SQL
- 請教個問題執行 httprunner 遇到的問題HTTP
- 【執行計劃】Oracle獲取執行計劃的幾種方法Oracle
- 多執行緒引起的效能問題分析執行緒
- [20240313]toad gather_plan_statistics執行計劃相關問題.txt
- [20210205]toad檢視真實執行計劃問題3.txt
- SQL最佳化案例-從執行計劃定位SQL問題(三)SQL
- SpringMVC中出現的執行緒安全問題分析SpringMVC執行緒
- SYBASE執行計劃
- MySQL 執行計劃MySql
- MySQL執行計劃MySql
- 如何縮小專案計劃與執行之間的差距?
- 一個nvcc編譯的小問題編譯
- pl/sql developer的一個小問題SQLDeveloper
- 一個極限小問題
- 記錄一個小問題
- 一個CRM OData的效能問題分析
- 一個RESOURCE MANAGER引起的問題分析