【数据库内核】基于规则优化之谓词重写

目录

概述

LIKE重写规则

一、情况一

二、情况二

BETWEEN-AND重写规则

一、情况一

二、情况二

IN转换OR重写规则

一、情况一

二、情况二

表达式语义去重重写规则

一、情况一

二、情况二

三、情况三

四、情况四

五、情况五

NOT重写规则

一、情况一

二、情况二

三、情况三

四、情况四

五、情况五

消除恒真重写规则

一、情况一

二、情况二

表达式剪枝重写规则

一、情况一

二、情况二

总结


概述

 

我们为什么要进行谓词表达式的重写,谓词表达式的重写的目的是什么?其实谓词表达式的的重写主要的优点就是能够更好的利用索引。使原先不能走索引的情况,改成可以通过索引优化。从而大大的提升了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 * 33. 满足乘法分配律X * (C1 + 3)

 

总结

 

表达式谓词重写的目的很简单,就是为了减少计算量,减少了计算量提升了CPU的执行效率,从而提升了总体的时间。并且通过表达式谓词的改写,可以更好的使用索引,使之前没有办法走索引的情况,通过改写可以更好的应用索引的技术。

多数谓词实现的都是局部环境下表达受限的语义,其对SQL语句的作用范围不够大,即其影响不够大,所以等价谓词重写属于局部优化技术。

分享大数据行业的一些前沿技术和手撕一些开源库的源代码
微信公众号名称:技术茶馆
微信公众号ID    :    Night_ZW

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值