本文隶属于专题系列: 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”表达式的优化。

摘自《数据库查询优化器的艺术》一书

你可能感兴趣的内容
0条评论

dexcoder

这家伙太懒了 <( ̄ ﹌  ̄)>
Owner