一次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更优。