從一條巨慢SQL看基於Oracle的SQL優化(重磅彩蛋+PPT)

本文根據DBAplus社羣第110期線上分享整理而成,文末還有好書送哦~算法

講師介紹sql

丁俊數據庫

新炬網絡首席性能優化專家性能優化

SQL審覈產品經理微信

  • DBAplus社羣聯合發起人、《劍破冰山-Oracle開發藝術》副主編網絡

  • Oracle ACEA,ITPUB開發版資深版主,十年電信行業從業經驗運維

本次分享的內容是基於Oracle的SQL優化,以一條巨慢的SQL爲例,從快速解讀SQL執行計劃、如何從執行計劃中找到SQL執行慢的Root Cause、統計信息與cardinality問題、探索性能殺手Filter操做、如何進行邏輯重寫讓SQL起飛等多個維度進行解析,最終優化巨慢SQL語句,但願可以拋磚引玉,和你們一塊兒探討SQL優化方法。ide

另外,還簡單介紹了兩種解決疑難SQL優化問題的工具:10053和SQLT,特別是SQLT,每每在機關用盡過程當中,可能創建奇功,建議你們抽空研究下SQLT工具。最後對本次分享進行總結和思考:分享SQL Tuning RoadMap以及SQL Tuning最佳實踐的相關內容。函數

大綱以下:工具

從一條巨慢的SQL開始

這條巨慢SQL執行預計耗時12小時以上,返回百萬行數據。首先咱們接手一條SQL優化問題,至少須要作如下兩件事:

  1. 瞭解SQL結構:SQL中使用了哪些語法,這些語法是否是常常會致使性能問題,好比標量子查詢的濫用。

  2. 獲取執行計劃:執行計劃反應了SQL的執行路徑,直接影響了SQL的執行效率。如何從執行計劃中找出問題,是SQL Tuning的關鍵。

言歸正傳,先揭開巨慢SQL的神祕面紗:

這條語句其實就是查詢DEALREC_ERR_201608表,有各類複雜的子查詢,初看此子查詢,我基本已經瞭解問題大概出在什麼地方了,先賣個關子,看執行計劃先:

這種執行計劃拿到手,其實很容易找出問題:

(1)分析指標問題:Rows,也就是每步驟的cardinality很小,說明每步返回的結果行數不多。這點值得懷疑。

(2)因爲cardinality不多致使了Operation走了一系列Nested Loops操做,咱們知道,NL操做,通常是驅動表返回的結果行數不多,被驅動表走索引,返回的最終結果比較少(通常最多幾千行),效率會很高。

以上兩點值得注意:若是cardinality是準確的,那麼這個執行計劃中走一系列Nested Loops的部分應該沒有多大問題,可是,若是cardinality不是準確的呢?那就是大問題。這也就是一些初級開發人員的思惟同樣,常常喜歡對數據的處理使用循環,若是循環的次數少那還好,若是循環次數不少,那就會很慢。循環操做徹底依賴於循環的次數,從SQL執行計劃裏看,也就是依賴於驅動表返回的結果行數,很顯然,這種不適合大量數據運算。

(3) 在ID=1中有個Filter,這個Filter的子操做是ID=15~18的全表掃描。Filter但是執行計劃裏的一個大問題,固然,這裏的問題Filter必須有2個或2個以上子節點的操做,若是是單節點,那只是簡單的過濾條件而已。

對於通常的SQL優化,必須得分析SQL的語法結構,語義以及解讀SQL執行計劃,以SQL執行計劃爲基準,分析執行計劃中的問題,來進行SQL Tuning,基本能解決大部分SQL優化問題了。

固然,以個人理解,SQL優化不只須要很強的邏輯思惟、正確的理論指導、各類SQL語法的精通、熟悉index的使用、瞭解CBO相關內容,甚至還需從大局觀進行把控:物理模型的設計以及對具體的業務分析。

快速解讀執行計劃

1

快速解讀執行計劃要點

SQL執行計劃做爲SQL優化的一把鑰匙,必需要很好地利用起來。常常看到開發人員喜歡用PL/SQL Developer之類的工具來看執行計劃。這裏我得提醒下,這種內部調用的是Explain Plan For,可能不夠準確,特別是有綁定變量的狀況下,最重要的一點,對於長的SQL執行計劃,簡直無法進行分析。我的仍是喜歡文本類型的執行計劃,特別是真實的執行計劃,能獲取A-ROWS,E-ROWS這些指標的執行計劃,讓我對執行計劃中的問題盡收眼底,特別對於巨慢的SQL,也能夠運行個幾分鐘中斷後獲取部分信息來協助判斷。

執行計劃要點以下:

  • 找入口:經過最右最上最早執行原則找出執行計劃入口操做。對於巨長執行計劃Copu到UE裏使用光標縮進下探法則可找出入口,因爲執行計劃是鋸齒狀結構,父節點的子操做是向右縮進的,所以,從ID=0開始,光標向下向右縮進下探,直到縮進不了中止,而後按照同級別的,也就是格式的垂直線是同一級的,上面的是入口。

  • 看關係:各操做之間的關係:Nesed Loops、HASH JOIN、Filter等是否準確,以及操做的順序是否準確,直接關係此操做甚至影響整個SQL的執行效率。

  • 理順序:一步走錯,滿盤皆輸。經過理清執行計劃順序找出key steps。

  • 重操做:執行計劃中的Operation和Predicate部分是須要關注的核心內容,從操做中看出不合理部分,以此創建正確索引等優化措施。

  • 求真實:執行計劃中指標是估算的,估算的指標和實際狀況極可能不匹配。因此優化SQL須要瞭解每步驟真實的基數、真實執行時間和Buffer gets等,從而準確找出問題Root cause。(能夠根據謂詞手動計算、建議採用display_cursor方式獲取A-ROWS、A-TIME等信息,工具備不少,也可使用sql monitor等),若是採用Explain Plan For、SET AUTOTRACE之類的看執行計劃,因爲指標信息是不許的,要獲取真實的信息,還須要手動根據謂詞去計算,而後比較估算的和真實的差異,從而判斷問題。

  • 輕成本:COST雖然是CBO的核心內容,但由於執行計劃中COST不必定準確反應SQL快慢,所以不要惟COST論,COST只是一個參考指標,固然能夠經過執行計劃判斷一些COST是否明顯存在問題,好比COST很是小,可是SQL執行很慢,可能就是統計信息不許確了。

2

快速解讀執行計劃實例

以上執行計劃入口是ID=6(全表掃描),返回行數1,以後與ID=7的作Nested Loops操做。詳細見分析部分。

  • 問題:爲何要尋找執行計劃入口?爲何要分析執行計劃各步驟順序和關係?

各類操做之間的關係是由cardinality等各類因素觸發的,不正確的cardinality會致使原本應該走HASH JOIN的走了Nested loops Join。每每入口處就有問題,致使後續執行計劃所有錯誤,因此明確各類步驟的關係,有助於找出影響問題的根源步驟。

理清執行計劃順序,有助於理解SQL內部的執行路徑,經過執行的實際狀況判斷出不合理步驟操做。

  • 重操做、求真實、輕成本是經過執行計劃優化SQL的重要方法。

這裏的入口是ID=6的全表掃描,返回行是1行,不是準確的,很顯然,找到入口的問題,已經能夠解決一部分問題了。

從執行計劃看SQL低效根源

  • 主表DEALREC_ERR_201608在ID=6查詢條件中經查要返回2000w行,計劃中估算只有1行,所以,會致使Nested Loops次數實際執行千萬次,致使效率低下。應該走HASH JOIN,須要更新統計信息。

  • 另外ID=1是Filter,它的子節點是ID=2和ID=1五、1六、1七、18,一樣的ID 15-18也被驅動千萬次。

找出問題根源後,逐步解決。

第一次分析:解決ID=6步驟估算的cardinality不許確問題。

統計信息與cardinality

1

解決cardinality估算不許確問題

  • 找出入口操做ID=6,因爲ID=6操做的cardinality估算爲1致使後續走一系列Nested Loops影響效率。

  • cardinality的計算與謂詞緊密相關,因此要找出ID=6的謂詞,根據謂詞手動計算真實card與估算card之間的區別。

  • 嘗試收集統計信息,檢驗效果。

如今的問題,也就是轉爲對錶DEALREC_ERR_201608統計信息準確性的問題,特別是統計信息對謂詞計算的準確性。

2

解決cardinality估算不許確問題-擴展統計信息收集

  • 嘗試更新統計信息:

發現使用size auto,size repeat,對other_class收集直方圖均無效果,執行計劃中對other_class的查詢條件返回行估算仍是1(實際返回2000w行)。如何解決?card的計算和謂詞緊密相關,查看謂詞:

substr(other_class, 1, 3) NOT IN (‘147’,‘151’, …)

怎麼辦?思緒萬千,靈光乍現!

Hints:cardinality(a,20000000),use_hash等能夠。

還有更好的辦法嗎?

忽然想起11g有個統計信息收集新特性:擴展統計信息收集。

exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>‘xxx',tabname=>‘DEALREC_ERR_201608',method_opt=>'for columns (substr(other_class, 1, 3)) size skewonly',estimate_percent=>10,no_invalidate=>false,cascade=>true,degree => 10);

擴展統計信息一收集,執行計劃以下:

  • DEALREC_ERR_201608與B_DEALING_DONE_TYPE原來走NL的如今正確走HASH JOIN。Build table是小結果集,probe table是ERR表大結果集,正確。

  • 可是ID=2與ID=11到14,也就是與TMI_NO_INFOS的OR子查詢,仍是FILTER,驅動數千萬次子節點查詢,下一步優化要解決的問題。

  • 性能從12小時到2小時。到這裏結束了嗎?

統計信息的問題仍是不少的,一個表的統計信息收集,特別是自動收集,不必定能讓全部相關SQL找到最佳執行路徑,特別是SQL條件複雜、數據傾斜、表類型定義不許確等狀況,特別是使用了複雜條件,CBO沒法準確計算對應謂詞的card,或者類型定義不許確,原本是日期的用了VARCHAR2,內部所有要轉爲數字來計算選擇性,很顯然,亂定義列類型也是有問題的。因此有針對性地修正收集的統計信息,是頗有必要的。

3

解決cardinality估算不許確問題-有關統計信息的那些疑問

  • 疑問1:100%收集爲何尚未走正確執行計劃?

統計信息收集比例高不表明就能夠翻譯對應謂詞的特徵,並且統計信息內部有不少算法限制以及不完善的狀況,好比11g的擴展統計信息來繼續完善,12c也有不少統計信息完善的特性。因此並非比例低就很差,比例高就好!統計信息的收集要知足核心SQL的執行效率,對於非核心SQL必定程度上能夠不用過分關注,由於統計信息很難知足全部相關SQL的最佳執行。

  • 疑問2:統計信息各類維度收集了包括直方圖都收集了怎麼不起做用?

直方圖有不少限制,12c以前,只有頻度直方圖和等高直方圖兩種,對不少值的分佈不能精確表示,因此有不少限制。所以,12c又增長了2種直方圖:頂級頻度直方圖和混合直方圖。另外直方圖還有隻存儲前32位字符的限制。

  • 疑問3:直方圖只對走索引的有做用?

很顯然不對,直方圖只是反應數據的分佈,數據的分佈正確,對應謂詞能夠查詢出比較準確的cardinality,從而影響執行計劃,因此對全表也是有用的。

  • 疑問4:收集或更新了統計信息,執行計劃怎麼變得更差了?

頗有可能,好比把原來的直方圖給去掉了可能致使執行計劃變差。所以,通常更新使用size repeat,除非是確認須要修改某些直方圖,另外謂詞和統計信息緊密相關,某些謂詞條件一旦收集統計信息,可能就計算不許確了。

  • 疑問5:執行計劃中cardinality顯示的和已有統計信息計算不一致?

Oracle CBO內部算法很複雜,並且Bug衆多,遇到問題要大膽懷疑。

  • 疑問6:統計信息應該按照Oracle建議自動收集?

具體問題具體分析,是讓Oracle自動仍是本身寫腳本收集,都須要長期實踐總結,對於一個複雜系統來講採樣比例和method_opt不少須要定製設置。

  • 疑問7:爲何惟一性很好的列,還須要收集直方圖?

選擇性的內部計算是要轉成數字的:CBO內部計算選擇性會先將字符串轉爲RAW,而後RAW轉爲數字,左起ROUND15位。若是字符串的惟一性好, 可是計算成數字後惟一性很差,則會致使執行計劃錯誤,這時候也須要收集直方圖。

  • 疑問8:我須要根據統計信息以及CBO公式去計算COST嗎?

不須要,除非你很喜歡研究,這樣作只會得不償失。瞭解各類JOIN算法、查詢轉換特性、索引等效率和哪些有關便可,COST不是最須要關心的指標,咱們應該關心SQL高效運行所需的執行路徑和執行方法,是否能夠達到及早過濾大量數據,JOIN方法和順序是否正確,是否能夠創建高效訪問對象等。

探索性能殺手Filter

1

性能殺手Filter造成機制

  • 爲何會造成Filter操做?(多子節點,單子節點純粹過濾操做)

Filter造成於查詢轉換期間,若是對於子查詢沒法進行unnest轉換來消除子查詢,則會走Filter。走Filter說明子查詢是受外表結果驅動,相似循環操做!很顯然,若是驅動的次數越多,效率越低!

查詢轉換是可以生成高效SQL執行計劃的重要步驟,查詢轉換不能作好,後面的不少執行路徑就無法走了。掌握查詢轉換機制,對如何寫高效的SQL,調優SQL相當重要,瞭解的越深,對CBO就越瞭解。

下面是CBO組件圖,熟悉對應組件是SQL優化必須的內容:

  • Filter何時高效?

Filter自己會構建HASH表來保存輸入/輸出對,以備後續減小子查詢執行次數,這是與純粹Nesed Loops操做的典型區別,好比from a where a.status In(select b.staus from b…)。 若是status前面已經查過,則後續不須要再次執行子查詢,而是直接從保存的HASH表中獲取結果,這樣減小了子查詢執行次數,從而提升效率。也就是說,若是子查詢關聯條件的重複值不少,Filter仍是有必定的優點,不然就是災難!

  • Filter與push_subq hints

若是走Filter則子查詢是受制於子查詢外結果集驅動,也就是子查詢是最後執行,可是實際有時候子查詢應該先執行效率更好,這時候可使用push_subq hints。

2

性能殺手Filter造成機制實例

  • 簡化前面的語句關鍵部分以下:

  • Oracle內部改寫以下,沒法unnest,若是unnest:

執行計劃以下:

從執行計劃裏能夠看到,Filter多子節點通常有以下特色:

  1. 自動生成的綁定變量:B1,由於須要執行循環操做

  2. 轉爲EXISTS

因此,之後看到有自動生成的綁定變量的執行計劃,都是相似Filter的操做,好比標量子查詢,UPDATE關聯子查詢,優化的話,都須要幹掉(類)Filter來優化。

這裏的例子實際上是一個CBO的限制:

  • 含有OR的子查詢,常常性沒法unnest,Oracle大多沒法給轉換成UNION/UNION ALL形式的查詢

  • 因此,針對這樣的語句優化:

    1)改寫爲UNION/UNION ALL形式

    2)根據語義、業務含義完全重寫

也就是說,須要重構查詢,消除Filter!慢的根源以下,這裏7萬多行,只執行了116行打印的執行計劃!ID=3~6的執行次數依賴於ID=2的結果行數,ID=3~6全表掃描次數太多。

邏輯重寫讓SQL起飛

1

邏輯改寫-構造高效HASH JOIN代替低效Filter

  • 回到原來的SQL中,看如何改寫,經過分析,能夠改成JOIN形式:

  • 改寫後執行時間從2小時到8分鐘,返回360w行+。雖然執行計劃更復雜了,可是充分利用了HASH JOIN、MERGE JOIN這種大數據量處理算法代替原來的Filter,更高效。若是不走OR擴展走什麼?(走Nested Loops,對IMS_NUM_INFO掃描從4次到1次,也很慢)。

  • OR擴展存在缺點,大表仍是屢次被訪問,還能繼續優化嗎?

2

完全重寫-消除OR擴展的HASH JOIN重寫思路

  • 上一次重寫,等於使用了第一種方法,用UNION/UNION ALL消除Filter,那麼如何消除UNION/UNION ALL呢,也就是要將OR語句合併爲AND!

追本溯源,從SQL含義出發,上面含義是ERR表的TMISID截取前8,9,10,11位與TMI_NO_INFOS.BILLID_HEAD匹配,對應匹配BILLID_HEAD長度正好爲8,9,10,11。很顯然,語義上能夠這樣改寫:

ERR表與TMI_NO_INFOS表關聯,ERR.TMISID前8位與ITMI_NO_INFOS.BILLID_HEAD長度在8-11之間的前8位徹底匹配,在此前提下,TMISID like BILLID_HEAD||’%’。

如今就動手完全改變多個OR子查詢,讓SQL更加精簡,效率更高。

3

完全重寫-消除OR擴展的HASH JOIN讓SQL起飛

經過上一節的思路,改寫SQL以下:

執行計劃以下:

  • 如今的執行計劃終於變的更短,更易讀,經過邏輯改寫走了HASH JOIN,那速度,槓槓的,最終一條返回300多萬行數據的SQL原先須要12小時運行的SQL,如今3分鐘就執行完了。

  • 思考:結構良好,語義清晰的SQL編寫,有助於優化器選擇更合理的執行計劃,看來編寫SQL真的有不少值得注意的地方。

兩個工具提高疑難SQL優化效率

1

兩個工具提高疑難SQL優化效率-10053分析執行計劃生成緣由

  • 一條SQL執行12分鐘沒有結果:其中object_id有索引,從查詢結構來看,內層查詢徹底能夠獨立執行(最多100行),而後與外層的表進行關聯,走NL,這樣能夠利用到object_id索引,然而,事與願違,ID=4出現Filter,這樣內層查詢會驅動N次,問題出在何處?

下面就使用10053探索優化器行爲來研究此問題。

*****************************

Cost-Based Subquery Unnesting

*****************************

SU: Unnesting query blocks in query block SEL$1 (#1) that are valid to unnest.

Subquery removal for query block SEL$3 (#3)

RSW: Not valid for subquery removal SEL$3 (#3)

Subquery unchanged.

Subquery Unnesting on query block SEL$2 (#2)SU: Performing unnesting that does not require costing.

SU: Considering subquery unnest on query block SEL$2 (#2).

SU: Checking validity of unnesting subquery SEL$3 (#3)

SU: SU bypassed: Subquery in a view with rowid reference.

SU: Validity checks failed.

  • 從10053中能夠看出,查詢轉換失敗,由於遇到了rowid,固然把Rowid改別名是能夠,可是此SQL要求必須用Rowid名字。

  • 經過改寫消除Filter運算以下:

2

兩個工具提高SQL優化效率-SQLT找出正確執行計劃需設置的參數

  • SQL可否生成正確執行計劃,不光和統計信息、索引等有關,可否正確執行查詢轉換是相當重要的,因爲各類複雜的查詢轉換機制致使Bug不少,Oracle對這些已知Bug經過fix control參數管理,有的默認打開,有的默認關閉。因此,若是遇到複雜的SQL,特別包含複雜視圖的SQL,好比謂詞沒法推入這種查詢轉換,收集統計信息無效,這時候能夠考慮是否遇到了Bug。

  • Bug那麼多,我怎麼知道是哪一個?SQLT神器來幫你!使用SQLT裏面的XPLORE工具,能夠把參數打開關閉一遍,而且生成對應執行計劃,這樣經過生成的報告,能夠一眼定位問題。(固然,是已知Bug,好比前面的Rowid問題,也是定位不到的)

  • 問題背景:11.2.0.2升級到11.2.0.4出現此問題,性能殺手Filter操做,SQL跑不出來,Filter產生緣由,沒法unnest subquery,其中11g _optimizer_null_aware_antijoin參數爲true。

執行計劃以下所示:

很顯然,這兩個Filter有問題,按理說應該走ANTI JOIN。

下面看看使用SQLT的XPLORE來找出問題,先來看下SQLT介紹:

跑一下XPLORE,只須要調用XPLAIN方法便可,提升效率,不實際執行SQL:

能夠看到和對應的隱含參數_optimizer_squ_bottomup設置有關,這是一個和子查詢的查詢轉換有關的隱含參數。

修正以後的執行計劃:

走回ANTI JOIN,正確了。終於從跑不出來到幾秒搞定,其實還能夠優化,可是那已經不是最重要的事了!

SQLT XPLORE的一些限制:

  • 只能單個參數測試是否有效;

  • 作XPLORE使用XPLAIN方法,內部調用explain plan for,不須要執行從而提升效率和避免修改數據;

  • 只有是已知參數或者Bug fix control纔會有用,對於未知Bug無用,固然修改參數須要作足測試,若是非批量問題,建議找出緣由,使用SQL PROFILE搞定,批量問題須要作足測試再實施修改!

SQL Tuning思考之RoadMap

  • 獲取問題SQL制定優化目標

從AWR、ASH、SQL CHECK S等主動發現有問題的SQL、用戶報告有性能問題時DBA介入等,經過對SQL的執行狀況分析,制定SQL的優化目標。

  • 檢查執行計劃

explain工具、sql*plus autotrace、dbms_xplan、1004六、1005三、awrsqrpt.sql等。

  • 檢查統計信息

Oracle使用DBMS_STATS包對統計信息進行管理,涉及系通通計信息、表、列、索引、分區等對象的統計信息,統計信息是SQL可以走正確執行計劃的保證。

  • 檢查高效訪問結構

重要的訪問結構,諸如索引、分區等可以快速提升SQL執行效率。表存儲的數據自己,如碎片過多、數據傾斜嚴重、數據存儲離散度大,也會影響效率。

  • 檢查影響優化器的參數

optimizer_mode、optimizer_index_cost_adj、optimizer_dynamic sampling、_optimizer_mjc_enabled、_optimizer_cost_based_transformation、hash_join_enable等對SQL執行計劃影響較大。

  • 優化器新特性、Bug

如11g的ACS、cardinality feedback、automatic serial direct path、extended statistics、SQL query result cache等。有的新特性會致使問題,需謹慎使用。

  • SQL語句編寫問題

SQL語句結構複雜、使用了不合理的語法,好比UNION代替UNION ALL可能致使性能低下。

  • 優化器限制

沒法收集準確的統計信息、沒法正確進行查詢轉換操做等,如SEMI JOIN、ANTI JOIN與or連用會走Filter操做。

  • 其餘

主要涉及設計問題,如應用在業務高峯期運行,實際上能夠放到較空閒狀態運行。表、索引、分區等設計不合理。

SQL Tuning最佳實踐:

SQL性能管理平臺

應用系統SQL衆多,若是老是做爲救火隊員角色解決線上問題,顯然不能知足當今IT系統高速發展的需求,基於數據庫的系統,主要性能問題在於SQL語句,若是能在開發測試階段就對SQL語句進行審覈,找出待優化SQL,並給予智能化提示,快速輔助優化,則能夠避免衆多線上問題。另外,還能夠對線上SQL語句進行持續監控,及時發現性能存在問題的語句,從而達到SQL的全生命週期管理目的。

針對以上種種,咱們新炬網絡以多年運維和優化經驗自主研發出了一款SQL審覈工具,經過SQL採集—SQL分析—SQL優化—上線跟蹤這四步SQL審覈法則, 極大地提高了SQL審覈優化和性能監控處理效率。有別於傳統的SQL優化方法,它是着眼於系統上線前的SQL分析和優化,重點解決SQL問題於系統上線以前,將性能問題扼殺於襁褓之中。

首頁審覈整體狀況盡收眼底:

審覈頁面展示詳細SQL審覈狀況:

SQL審覈結果多維護分析:

優化建議詳細準確:

內置上百種規則集,可按需選擇:

SQL性能管理平臺必須解決事前事中過後的SQL全生命週期管理問題。

  • 事前:上線前SQL性能審覈,扼殺性能問題於襁褓之中。

  • 事中:SQL性能監控處理,及時發現上線後SQL性能發生的變化,在SQL性能變化而且沒有引發嚴重問題時,及時解決。

  • 過後:核心SQL監控,及時告警處理。

SQL性能管理平臺實現了SQL性能的360度全生命週期管控,而且經過各類智能化提示和處理,將絕大多數原本因SQL引起的性能問題,解決在問題發生以前,提升系統穩定度。

另外對SQL性能的分析,從SQL寫法、SQL執行信息、執行計劃、統計信息等多方面定義規則,多維度進行分析,提供智能化的建議,提高優化速度和準確性。

SQL性能管理平臺特色-自動化採集、分析、跟蹤,減小DBA分析時間,提升管控效率:

SQL審覈是新炬網絡數據庫性能管理平臺DPM的一個模塊,你們若想了解更多關於DPM的信息,可加鄒德裕大師微信carydy交流探討。

Q&A

Q1:merge join、nested loops、hash join何時走什麼樣的鏈接呢?

A1:Nested loops適合各類關聯條件的查詢,=,<>,>,<等等,主要是驅動行數少,被驅動的若是有高效索引,返回結果集不大的狀況下高效,側重於CPU消耗。

HASH JOIN是必需要等值鏈接的,側重於大數據量運算,本次分享的巨慢SQL就是經過將OR子查詢經過SUBSTR函數構造等值鏈接,實現HASH JOIN運算,側重於內存消耗。

SORT MERGE JOIN主要適合<,>之類的大數據量運算,須要排序,側重於內存消耗。

Q2:收集統計信息用analyze仍是dbms_stats?

A2:很顯然收集統計信息要用DBMS_STATS,ANALYZE有些功能DBMS_STATS沒有,好比validate structure等。

Q3:SQL第一次快,以後執行慢大概什麼緣由?

A3:這種問題須要具體分析了,若是是11g,大可能是執行計劃頻繁變化致使的,11g有cardinality feedback和adaptive cursor sharing,BUG較多,常常會致使SQL忽快忽慢,能夠經過執行計劃來進行分析,若是是這樣的緣由,能夠關閉此特性。若是不是新特性致使的,能夠經過分析物理讀,邏輯讀,或者10046跟蹤來找出緣由加以解決。

下載連接

一、分享PPT下載:

點擊文末【閱讀原文】或登陸雲盤:http://pan.baidu.com/s/1kVSLFlt,便可下載本次分享PPT。

二、直播連接:

https://m.qlchat.com/topic/220000485078915.htm?preview=Y&intoPreview=Y

密碼:006

好書相送

在本文微信訂閱號(dbaplus)評論區留下足以引發共鳴的真知灼見,並在本文發佈後的隔天中午12點成爲點贊數最多的1名,可得到絕版譯著《Oracle核心技術》一本~

精選專題(官網:dbaplus.cn)

◆ 近期活動 ◆

DAMS中國數據資產管理峯會上海站

峯會官網:www.dams.org.cn返回搜狐,查看更多

聲明:該文觀點僅表明做者本人,搜狐號系信息發佈平臺,搜狐僅提供信息存儲空間服務。
相關文章
相關標籤/搜索