一次sql優化的機會,被where條件,索引,優化器這三者的決定關係混淆,藉助這個問題整理以下:sql
1.概念函數
表T1上有列C一、C二、C三、C四、C五、C六、C七、C8。其中在C1,C2,C3,C4上有索引C1234X。優化
A.查詢語句:Select * From T1 Where C1=5 And C2=4 And C3=7 And C4=2spa
該語句使用索引C1234X,匹配謂詞爲C1=五、C2=四、C3=七、C4=2。使用這些謂詞能夠直接完成定位,無需進行索引頁的逐個掃描。.net
D.查詢語句:Select * From T1 Where C2=4 And C3=7 And C1=5blog
該語句使用索引C1234X,匹配謂詞爲C1=五、C2=四、C3=7。注意,對應Where子句後面的謂詞,優化器會根據索引中列的順序進行從新排序(查詢重寫)。排序
E.查詢語句:Select * From T1 Where C1=5 And C2=4 And C4=2 And C6=10索引
該語句使用索引C1234X,匹配謂詞爲C1=五、C2=4,篩選謂詞爲C4=2,C6=10爲普通謂詞(沒有索引與之對應)。能夠看到,一旦謂詞對應的索引列不連續,那麼其後的索引列對應的謂詞就只能是篩選謂詞了。由於一旦不連續,那麼該謂詞就不能繼續使用樹結構進行定位了,只能對下層索引頁進行逐個掃描。get
F.查詢語句:Select * From T1 Where C1=5 And C2=4 And C3>7 And C4=2it
該語句使用索引C1234X,匹配謂詞爲C1=五、C2=四、C3>7,篩選謂詞爲C4=2。一直到C3都可以使用樹結構進行定位,可是C4就不行了,由於C3>7給的只是一個範圍,該範圍內的下層索引頁只能由C4謂詞進行逐個掃描篩選了。
表T上有列C一、C二、C三、C四、C五、C六、C七、C8。其中在C1,C2,C3,C4上有索引C1234X;C五、C6上有索引C56X;C7上有惟一索引C7X。
用ACCESSTYPE表示訪問類型,ACCESEETYPE=I表示使用索引掃描,ACCESSTYPE=N表示使用帶In-list謂詞的索引掃描。ACCESSNAME表示使用的索引。MATCHCOLS表示匹配的索引列數。對照上面的規則,再也不進行詳細解釋了。
Select * From T Where C1=5 And C2=7 And C5=8 And C6=13
ACCESEETYPE=I , ACCESSNAME=C56X , MATCHCOLS=2 //至於爲何使用的是索引C56X而不是C1234X,這是由優化器的成本估算結果決定的。
Select * From T Where C1=5 And C2 in(5,6) And (C3=10 or C4=11)
ACCESEETYPE=N , ACCESSNAME=C1234X , MATCHCOLS=2 //"or"操做符鏈接的謂詞會被看成不可索引謂詞,所以不是匹配謂詞,可是能夠做爲篩選謂詞。
Select * From T Where C1=5 And C2=7 And C7=101
ACCESEETYPE=I , ACCESSNAME=C7X , MATCHCOLS=1 //一般惟一索引會優於普通索引,但也不是絕對的。
Select * From T Where C2=7 And C3=10 And C4=12 And C5=16
ACCESEETYPE=I , ACCESSNAME=C1234X , MATCHCOLS=0 //雖然C1234X上沒有匹配謂詞,C56X上有,可是優化器認爲使用索引C1234X更優。