Oracle調優之no_unnest和unnest用法簡介


Oracle調優之no_unnest和unnest用法簡介

本博客介紹Oracle SQL調優的一種常用也是很實用的方法,也即/*+no_unnest *//*+ unnest*/ ,介紹Oracle 的 /*+unnest *//*+ no_unnest */ 之前,先介紹一下Hint。

Hint對於開發人員來說,可能不是很熟悉,但是對於DBA來說,Hint可是一種調優的利器,Hint 是Oracle 提供的一種SQL語法,是oracle早期因為oracle優化器還不是很完善加上去的,可以輔助oracle優化器,常用於SQL調優,通過Hint強行改變Oracle的執行計划,從而實現SQL調優

也就是說Hint語法可以人工地干預Oracle優化器選擇執行計划,當然Hint雖然很實用,但是用的不好,也必然影響SQL性能,國內DBA大牛在其博文里就有曾提到,引用其博文的觀點:

在這里插入圖片描述
在這里插入圖片描述
詳情可以參考作者博文:https://dbaplus.cn/news-10-669-1.html

ok,有了前面的必要知識后,可以介紹一下Oracle的Hint語法之no_unnest和unnest用法了,no_unnest、unnest顯然是一對相對的用法

  • unnest:也即解嵌套,nest是嵌套的意思,也就是讓子查詢展開查詢,和外部的查詢進行關聯、合並,從而得到執行計划
  • no_unnest:雙重否定表肯定,也是子查詢嵌套(nest),讓子查詢不展開,這時候子查詢往往是最后執行的,作為FILTER條件來過濾外部查詢

對於hint語法來說,形式就是/*+ .... */的形式,所以對於這兩種嵌套和解嵌套查詢,其用法分別為/*+ no_unnest *//*+ unnest*/,加在子查詢的select關鍵字后面即可,我之前博客曾經整理過Hint的常用語法,詳情參考我博客Oracle之Hint用法整理筆錄

案例記錄,ok,最近遇到一個sql查詢需要超過1分鍾的情況,因為是生產環境問題,比較緊急,業務又特別復雜,SQL很復雜,關聯了十幾張表(業務需要),如果通過改寫sql來調優,比較花時間,業務不夠熟悉的情況,所以,首先我也是先通過加必要索引的方式,檢查主鍵、外鍵是否都有索引了,索引也不能亂叫,還要分析哪些表更新比較多的,然后我是想到hint調優,雖然hint有局限性是在某些sql不改寫的情況是可以起到作用的,如果sql改變,hint語法很有可能影響SQL性能,所以使用hint調優並非上策

我遇到的sql是很復雜的,不過本文進行簡單描述,其SQL語法類似如下,省略很多的情況:

select id,....,from t1 left join t2 where t2.id in (select k from t1 where ...) ....

首先,我想到用子查詢解嵌套方式,進行改寫:

select id,....,from t1 left join t2 where t2.id in (select /*+ unnest */ k from t1 where ...) ....

然后通過執行計划查詢,性能並沒有提升,unnest是讓子查詢展開,和外部的查詢進行關聯、合並,首先t1是一張數據量很多的表,然后SQL里先left join了t1,又在子查詢里使用了t1,如果unnest的話,不是會進行自連接?所以我改成/*+ no_unnest */,不讓子查詢展開,讓子查詢最后執行,作為一個filter條件,經過實驗,sql查詢從1分鍾以上都0點及秒

ok,說明一下,本人水平並沒有dba水平,對於SQL調優沒有豐富經驗,所以請作者可以不管我的案例,只要理解unnest和no_unnest的用法即可,sql調優是很復雜,需要很多調優經驗才可以做到游刃有余的,本博客觀點,僅代表本人觀點,因為對sql調優本沒有深入理解,所以也並沒有特別推崇使用unnest或者no_unnest,這兩種用法具體在什么環境使用適宜?在網上也沒有找到特別明確的說明,所以遇到sql性能問題,通過分析執行計划是最有用的

附錄:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM