注册
DM7操作符优化系列(三)——过滤条件操作符SLCT

DM7操作符优化系列(三)——过滤条件操作符SLCT

Grrr 2020/12/14 2697 12 0
摘要 从过滤条件操作符的描述信息中,我们可以看到对于下层操作有哪些可用的过滤条件,进而决定优化方向。

过滤条件:SLCT

这类操作符比较简单,是对结果集进行过滤,需要注意的是这类操作符的描述信息,从描述信息中我们可以看到对于下层操作有哪些可用的过滤条件,这些过滤条件往往是优化方向的来源。

延用上篇文章DM7操作符优化系列(二)——多表关系处理中的测试用表

CREATE TABLE T1(ID VARCHAR); CREATE TABLE T2(ID VARCHAR); INSERT INTO T1 VALUES('AMEE'),('AMSS'),('BURNING'),('ABED'),('CHALICE'); INSERT INTO T2 VALUES('AAAA'),('AAAA'),('BBBB'),('CCCC'),('DDDD'),('AAME'),('AMEE'),('EEEE');
--SEL 14 EXPLAIN SELECT * FROM T2 WHERE ID > 5 AND ID NOT LIKE '%C%'; 1 #NSET2: [0, 1, 56] 2 #PRJT2: [0, 1, 56]; exp_num(2), is_atom(FALSE) 3 #SLCT2: [0, 1, 56]; (exp_cast(T2.ID) > 5 AND exp11 <= 0) 4 #CSCN2: [0, 8, 56]; INDEX33555447(T2)

需要关注的是SLCT的描述部分 (exp_cast(T2.ID) > 5 AND exp11 <= 0),这里的描述部分将查询条件中的 ID > 5 标注为了 EXP_CAST(T2.ID) > 5,ID NOT LIKE ‘%c%’ 标注为了 EXP11 <= 0

其中 EXP_CAST(T2.ID) > 5 提供的信息告诉我们,列 ID 和数字 5 进行比较时,是要对列作类型转换的,那么也就是说,就算 ID 列上存在索引,可能也不能进行范围扫描,因为索引范围扫描的输入要求是和索引列上的数据类型相同,我们验证一下

--SEL15 CREATE INDEX I_INDEX3 ON T2(ID); EXPLAIN SELECT * FROM T2 WHERE ID = 5; 1 #NSET2: [0, 1, 56] 2 #PRJT2: [0, 1, 56]; exp_num(2), is_atom(FALSE) 3 #SLCT2: [0, 1, 56]; exp_cast(T2.ID) = 5 4 #CSCN2: [0, 8, 56]; INDEX33555447(T2)

确实,在存在索引 (I_INDEX3) 的情况下,单列等值查询也没有走索引进行查询。

这个例子也说明了一个大致原理:在 DM7 中,内部提供多种对比数据的方法以及转换类型的方法,但这些方法是没有覆盖所有类型的,不同类型数据进行比较时,会先选取一种用于比较的数据类型,再确定比较方法。

比如在此例中,比较 ID(VARCHAR) = 5(INT),服务器优先选择把类型转换成INT进行比较,导致ID列需要做类型转换,从而不能利用索引(索引存储的是转换之前的数据)。碰到这种情况,我们需要把索引列的对比对象(此例中的INT)转换为和索引列一样的类型。

--SEL16 EXPLAIN SELECT * FROM T2 WHERE ID = '5'; 1 #NSET2: [0, 1, 56] 2 #PRJT2: [0, 1, 56]; exp_num(2), is_atom(FALSE) 3 #SSEK2: [0, 1, 56]; scan_type(ASC), I_INDEX3(T2), scan_range['5','5']

将 ID(VARCHAR) = 5(INT) 中的 5(INT) 转换为 5(VARCHAR) 之后,就走索引进行查询了。

对于过滤条件操作符,我们希望做到的是:对于SLCT描述项中的每一个具体描述,都能在原始SQL查询语句中找到对应的条件,并思考是否存在优化的可能性。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服