目录
概述
我们为什么要进行谓词表达式的重写,谓词表达式的重写的目的是什么?其实谓词表达式的的重写主要的优点就是能够更好的利用索引。使原先不能走索引的情况,改成可以通过索引优化。从而大大的提升了SQL的计算性能并且降低了SQL的执行时间。
LIKE重写规则
一、情况一
SQL样式:
c1 like 'abc%'
优化后的样式:
c1 ≥ 'abc X X X ' and c1 ≤ 'abc Y Y Y'
如果将 c1 用作索引的前导列,那么 Db2 会生成这些谓词,以便它们可作为范围定界开始-结束谓词进行应用。此处字符 X 和 Y 是最低和最高整理字符的符号。
二、情况二
SQL样式:
c1 like 'abc%def'
优化后的样式:
c1 ≥ 'abc X X X ' and c1 ≤ 'abc Y Y Y' and c1 like 'abc%def'
这与先前情况类似,只是您还必须将原始谓词作为索引控制谓词应用。这样可确保字符 def 正确匹配。
BETWEEN-AND重写规则
BETWEEN-AND谓词,是SQL标准支持的一种范围比较操作;
BETWEEN-AND规则,是BETWEEN-AND谓词的等价重写,即改写BETWEEN-AND谓词为其他等价的谓词,以更好地利用索引进行优化。
一、情况一
SQL样式:
TEXT BETWEEN '100' AND '102'
优化后的样式:
TEXT >= '100' AND TEXT <= '102'
Oracle计划信息如下:
二、情况二
SQL样式:
TEXT NOT BETWEEN '100' AND '102'
优化后的样式:
TEXT < '100' OR TEXT > '102'
Oracle计划信息如下:
应用BETWEEN-AND规则的好处是:
如果text上建立了索引,则可以用索引扫描代替原来BETWEEN-AND谓词限定的全表扫描,从而提高了查询的效率。
IN转换OR重写规则
说明:IN是只IN操作符操作,不是IN子查询。
IN转换OR规则,就是IN谓词的OR等价重写,即改写IN谓词为等价的OR谓词,以更好地利用索引进行优化。将IN谓词等价重写为若干个OR谓词,可能会提高执行效率。
一、情况一
SQL样式:
TEXT IN ('100','101','201')
优化后的样式:
TEXT ='100' OR TEXT ='101' OR TEXT ='201'
Oracle计划信息如下:
二、情况二
SQL样式:
TEXT NOT IN ('100','101','201')
优化后的样式:
TEXT <>'100' AND TEXT <>'101' AND TEXT <>'201'
Oracle计划信息如下:
应用IN转换OR规则后效率是否能够提高,需要看数据库对IN谓词是否只支持全表扫描。
如果数据库对IN谓词只支持全表扫描且OR谓词中表的text列上存在索引,则转换后查询效率会提高。
表达式语义去重重写规则
表达式语义去重的含义是减少表达式的计算量,通过表达式的语义来减少计算,以更好地利用MIN/MAX操作进行优化。
一、情况一
SQL样式:
TEXT > '100' OR TEXT > '101' OR TEXT > '102'
优化后的样式:
TEXT > '100'
Oracle计划信息如下:
二、情况二
SQL样式:
TEXT > '100' AND TEXT > '101' AND TEXT > '102'
优化后的样式:
TEXT > '102'
Oracle计划信息如下:
三、情况三
SQL样式:
TEXT > '100' AND TEXT > '101' OR TEXT > '102'
优化后的样式:
TEXT > '101'
Oracle计划信息如下:
四、情况四
SQL样式:
TEXT > ANY('100', CONCAT('10','2'), '101')
优化后的样式:
TEXT > '100'
Oracle计划信息如下:
五、情况五
SQL样式:
TEXT > ALL('100', CONCAT('10','2'), '101')
优化后的样式:
TEXT > '102'
Oracle计划信息如下:
NOT重写规则
NOT谓词的等价重写,如下:
一、情况一
SQL样式:
NOT C1 != 2
优化后的样式:
C1 = 2
Oracle计划信息如下:
二、情况二
SQL样式:
NOT C1 != C2
优化后的样式:
C1 = C2
Oracle计划信息如下:
三、情况三
SQL样式:
NOT (C1 = C2)
优化后的样式:
C1 != C2
Oracle计划信息如下:
四、情况四
SQL样式:
NOT (C1 < C2)
优化后的样式:
C1 >= C2
Oracle计划信息如下:
五、情况五
SQL样式:
NOT (C1 > C2)
优化后的样式:
C1 <= C2
Oracle计划信息如下:
消除恒真重写规则
如果表达式的语义是恒真或者恒假的情况,直接化简表达式或者删除表达式,减少计算量,从而提升性能。
一、情况一
SQL样式:
1 = 1 OR C1 > 10 OR C2 = 20
优化后的样式:
表达式会被删除
Oracle计划信息如下:
二、情况二
SQL样式:
1 != 1 AND C1 > 10 AND C2 = 20
优化后的样式:
表达式会返回恒假
Postgre sql计划信息如下:
表达式剪枝重写规则
如果表达式中有相同的计算片段,可以裁剪成一个提前计算,其他计算片段直接读取提前计算好的结果,减少计算量,从而提升了性能。
一、情况一
SQL样式:
(C1 + 2) * (C1 + 2) + 3 = 10
优化后的样式:
1. 提取相同子表达式
X = (C1 + 2)
2. X带入原始表达式
X * X + 3 = 10
oceanbase采用这样的手段来降低表达式计算的量。相同的子表达式越复杂,提升性能越明显。但是有一些报错场景可能不太适用,具体问题具体分析了。
二、情况二
SQL样式:
(C1 + C2) * C1 + (C1 + C2) * 3
优化后的样式:
1. 提取相同表达式
X = (C1 + C2)
2. X带入原始表达式
X * C1 + X * 3
3. 满足乘法分配律
X * (C1 + 3)
总结
表达式谓词重写的目的很简单,就是为了减少计算量,减少了计算量提升了CPU的执行效率,从而提升了总体的时间。并且通过表达式谓词的改写,可以更好的使用索引,使之前没有办法走索引的情况,通过改写可以更好的应用索引的技术。
多数谓词实现的都是局部环境下表达受限的语义,其对SQL语句的作用范围不够大,即其影响不够大,所以等价谓词重写属于局部优化技术。