SQL最佳化--邏輯最佳化--條件化簡,sql--
1)查詢條件
查詢條件概念:
SQL查詢語句中,對元組進行過濾和串連的運算式,形式上是出現在WHERE/JOIN-ON/HAVING的子句中的運算式。
2)條件化簡技術
①條件下推:把與單個表相關的條件,放到對單表進行掃描的過程中執行。
SELECT *
FROM A, B
WHERE A.a=1 and A.b=B.b;
執行順序:
a)掃描A表,並帶有條件A.a=1,把A表作為嵌套迴圈的外表
b)掃描B表,執行串連操作,並帶有過濾條件A.b=B.b
說明:資料庫系統都支援條件下推,且無論條件對應的列對象有無索引。系統自動進行最佳化,不用人工介入。
②條件化簡
a)把HAVING條件併入WHERE條件(MySQL不支援)
優點:便於統一、集中化解條件子句,節約多次化解時間。
注意:不是任何情況下HAVING條件都可以併入WHERE條件,只有在SQL語句中不存在GROUPBY條件或聚集合函式的情況下,才能將HAVING條件與WHERE條件的進行合并。
DB> select * from t3 where a3>1 having b3=3; 化簡為:
select * from t3 where a3>1 and b3=3;
b)去除運算式中冗餘的括弧(MySQL支援)
優點:可以減少文法分析時產生的AND和OR樹的層次。---減少CPU的消耗
樣本:
((a AND b) AND (c AND d)) 化簡為: a AND b AND c AND d
c)常量傳遞(MySQL支援)
優點:對不同關係可以使得條件分離後有效實施“選擇下推”,從而可以極大減小中間關係的規模。
樣本:
col_1 = col_2 AND col_2 = 3 化簡為: col_1=3 ANDcol_2=3
注意:操作符“=、<、>、<=、>=、<>、<=>、LIKE”中的任何一個,在“col_1 <操作符> col_2”條件中都可能會發生常量傳遞。
d)消除死碼(MySQL支援):化簡條件,將不必要的條件去除。
樣本:
WHERE(0 > 1 AND s1 = 5),“0 > 1”使得AND恒為假,則WHERE條件恒為假。此時就不必要再對該SQL語句進行最佳化和執行了,加快了查詢執行的速度。
e)運算式計算(MySQL支援):對可以求解的運算式,進行計算,得出結果。
樣本:
WHERE col_1 = 1 + 2 變換為: WHERE col_1 =3
f)等式變換(MySQL不支援)
化簡條件(如反轉關係操作符的運算元的順序),從而改變某些表的訪問路徑
樣本:
-a = 3 可化簡為: a = -3
這樣的好處是如果a上有索引,則可以利用索引掃描來加快訪問。
g)不等式變換(MySQL不支援)
化簡條件,將不必要的重複條件去除。
樣本:
a > 10 AND b = 6 AND a > 2 可化簡為: b = 6 AND a > 10
h)布林運算式變換
(1)謂詞傳遞閉包(MySQL不支援)
一些比較操作符,如“<”、“>”等,具有傳遞性,可以起到化簡運算式的作用
樣本:
a>b AND b>2 可以推匯出a>b AND b>2 ANDa>2,“a>2”是一個隱含條件,這樣把“a>2”和“b>2”分別下推到對應的關係上,就可以減少參與比較操作“a>b”的元組了。
(2)布林運算式被轉換為一個等價的合取範式(CNF)(MySQL支援)
任何一個布林運算式都能被轉換為一個等價的合取範式(CNF),合取範式格式為:C1 AND C2 AND… AND Cn;其中,Ck(1<=k<=n)稱為合取項,每個合取項是不包含AND的布林運算式。
說明:
①合取項只要有一個為假,整個運算式就為假,故代碼中可以在發現一個合取項為假時,即停止其他合取項的判斷,加快判斷速度;
WHERE(0 > 1 AND s1 = 5)
①另外因為AND操作符是可交換的,所以最佳化器可以按照先易後難的順序計算運算式,一旦發現一個合取項為假時,即停止其他合取項的判斷,加快判斷速度。
WHERE(A.a+B.b > 100 AND A.b = 5 AND 0 > 1 )
先求解:0 > 1 ,值為假,其他不再求解
(3)索引利用 (MySQL支援)
如果一個合取項上存在索引,則先判斷索引是否可用,如能利用索引快速得出合取項的值,則能加快判斷速度。同理,OR運算式中的子項也可以利用索引
樣本:
WHERE (A.a> 100 AND A.b = 5 AND... )
情況1:A表的a列上存在索引,b列無索引,則利用a上的索引找出元組,“A.b = 5” 作為過濾條件使用。
情況2:A表的a列上不存在索引,b列有索引,則利用b上的索引找出元組,“A.a> 100” 作為過濾條件使用。
i)IS NULL運算式最佳化(MySQL支援)
利用索引,支援“IS NULL”運算式的最佳化。
摘自《資料庫查詢最佳化工具的藝術》一書