高性能SQL 筆記(1)

——SQL語句改寫

這星期沒干啥別的,把這本書粗粗?jǐn)]了一遍,數(shù)據(jù)庫基礎(chǔ)差,平時也就寫寫增刪改查,感覺看了一遍,概念知道了不少,但是感覺啥也沒學(xué)會,以后玄學(xué)寫sql的嘗試范圍可能變的更廣泛了??,慢慢來吧。
看了一遍,暫時簡單上手的大概就是第十章里的sql改寫,還有就是看看十一章里的例子圍觀一下。

image.png

在排除了CBO出現(xiàn)問題需要借助Hint的情況下,簡單的邏輯一般通過slq改寫來優(yōu)化基本夠用了。

一般性原則:

  1. 能用join的,不要用in和not in子查詢
  2. 能用in子查詢的,不要用exists相關(guān)查詢
  3. 能用not exists相關(guān)子查詢的,不要用not in子查詢

(所有場景都是以sql存在性能問題為前提)

1. 消除查詢中的視圖(view):

場景:

  • from中連接數(shù)據(jù)對象比較多
  • 視圖子查詢from中連接數(shù)據(jù)對象比較多
  • 視圖嵌套層次比較多

2. 標(biāo)量子查詢改為外連接:

標(biāo)量子查詢這個詞看的我一臉蒙蔽:Oracle允許在select子句中包含單行子查詢,這個也就是oracle的標(biāo)量子查詢,標(biāo)量子查詢有點(diǎn)類似于外連接,當(dāng)使用到外連接時我們可以靈活的將其轉(zhuǎn)化為標(biāo)量子查詢。
好吧,就是select 里加了個查詢

注意:

  • 原標(biāo)量子查詢下沉為內(nèi)嵌視圖時,需要和原主查詢表進(jìn)行outer join
  • 存在多個標(biāo)量子查詢時,分別改為相應(yīng)內(nèi)嵌視圖并下沉,同時分別和主查詢表進(jìn)行outer join

3. update改為merge into

傳說中大數(shù)據(jù)環(huán)境下的利劍merge into,沒接觸過。
說明:MERGE語句是Oracle9i新增的語法,用來合并UPDATE和INSERT語句。
通過MERGE語句,根據(jù)一張表或子查詢的連接條件對另外一張表進(jìn)行查詢,
連接條件匹配上的進(jìn)行UPDATE,無法匹配的執(zhí)行INSERT。
這個語法僅需要一次全表掃描就完成了全部工作,執(zhí)行效率要高于INSERT+UPDATE

場景:

  • update語句中存在相關(guān)子查詢

4. 正確使用分析函數(shù)

利用分析函數(shù)來改寫匯聚相關(guān)的sql語句
場景:

  • 原sql語句執(zhí)行計劃中存在對同一數(shù)據(jù)對象的多次掃描

5. with as 去除多次掃描

with as 語句可以動態(tài)地創(chuàng)建一個臨時表,用以存儲中間數(shù)據(jù)
注意:

  • 改寫為with as 語句時,注意要抽取所有相關(guān)的子查詢的最大集合(超集),并合理消除所有或部分相關(guān)的子查詢
  • 改寫時如果存在多個臨時表,那么后面的臨時表應(yīng)盡量利用前面的臨時表

場景:

  • sql中子查詢導(dǎo)致執(zhí)行計劃中對某個或某些數(shù)據(jù)對象的多次掃描,且子查詢結(jié)果集足夠小
  • 原sql中子查詢在執(zhí)行計劃中已展開

6. union 改為 or

場景:

  • sql中子查詢在執(zhí)行計劃中已展開
  • sql中子查詢導(dǎo)致執(zhí)行計劃中對相關(guān)對象掃描次數(shù)過多
  • sql中子查詢在執(zhí)行計劃中對相關(guān)索引的使用情況不理想

7. or 改為 union

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中對相關(guān)索引的使用情況不理想

8. in 改為 join

注意:

  • in改為join后,需要將結(jié)果集去重(distinct)

場景:

  • sql中子查詢在執(zhí)行計劃中未展開

9.in 改為exists

注意:

  • in改為exists時,注意相關(guān)子查詢的where條件和select-list

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中已展開,且主查詢及子查詢相關(guān)表間連接效果不理想

10. not in 改為 not exists

注意:

  • 注意相關(guān)子查詢的where條件和select-list

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中已展開,且主查詢及子查詢相關(guān)表間連接效果不理想

11. not exists 改為 not in

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中已展開

12. exists 改為 join

注意:

  • exists改寫為join的過程中,注意sql語句中where的合并

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中已展開,且主查詢及子查詢相關(guān)表間連接效果不理想

13. not exists 改為 join

場景:

  • sql中子查詢在執(zhí)行計劃中未展開
  • sql中子查詢在執(zhí)行計劃中已展開,且主查詢及子查詢相關(guān)表間連接效果不理想

14. join 改為 exists

注意:

  • 注意sql中where條件的分解

場景:

  • sql語句執(zhí)行計劃中相關(guān)表間連接效果欠佳

15. join 改為 not exists

注意:

  • 注意sql中where條件的分解

場景:

  • sql語句執(zhí)行計劃中相關(guān)表間連接效果欠佳

16. 改寫為集合運(yùn)算符

集合運(yùn)算符,主要包括:unionminus ,intersect 等,用來完成數(shù)據(jù)集間的操作

注意:

  • sql語句where條件,乃至整個語句的分解

場景:

  • 原sql語句執(zhí)行計劃中相關(guān)索引使用情況不理想
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容