[Mycat2]索引字段分析-2021-4-21

author:chenjunwen 2021-4-21
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

 

 Mycat2是分库分表型数据库(中间件),具有逻辑库,逻辑表概念,其中对于分片表类型,使用特定的规则组织'行数据'在多个物理表中存储.而SQL查询分片表的时候,正确使用谓词,Mycat2分析出仅需扫描的物理表,则可在执行阶段大大减少需要使用的连接,IO耗时,因为谓词不符合数据分布,查询的结果集就是空的.(v1.18提供索引字段分析)

 在分库分表数据库中,使用不同的数据定位字段减少扫描的范围,它们是分表键,分库键,全局二级索引等.下推它们有着索引字段分析相似的功能.索引字段分析在数据库中至关重要.通常我们判断SQL能否使用哪种扫描数据方式就可以大致判断SQL的查询效率,对于分库分表中间件来说,尽可能减少扫描范围,甚至严格保证扫描的存储节点只有一个存储节点才是正确的用法.

 

索引字段分析的工作过程

image.png

 

 

非DNF检查

 首次,优化器会提取下压到表扫描算子上的谓词,并把他们做disjunction(DNF)转换,试图得到一组or相邻的表达式,如果该表达式的数量是1,则表示该组表达式没有or运算,则可继续进行谓词分析,否则不满足谓词分析约束.

image.png

RexNode:{id = 1 or id  = 2} → List<RexNode>[{id = 1},{id = 2}]

W=P1∨P2∨P3∨...Pn

特殊表达式扩展

 其次,对谓词表达式扩展.在这里我们可以把一些特殊意义的表达式扩展,比如

 id between 1 and 3 →  1 <= id and id <= 3

 这样的好处与括号()表达优先级差不多,表示该表达式是一个整体,它们不被CNF/DNF影响.

CNF扩展

然后,对谓词进行CNF分析.得到一组and相邻的表达式.

RexNode:{id = 1 and id  = 2} → List<RexNode>[{id = 1},{id = 2}]

W=P1^P2^P3^...Pn

索引应用

因为分片表可能存在多个索引信息,它们依次应用CNF扩展的结果.

提取索引字段

使用谓词检查语法检查and表达式中的每个表达式,提取scan_binary_expr这个层次的语法树,检查其中的字段是否索引字段,把它们转换成谓词节点并依照遍历顺序收集起来,与常规的解析器不同不符合语法的部分不会发生异常,直接跳过.

谓词检查语法

 

and_expr : scan_binary_expr 'AND' scan_binary_expr

scan_binary_expr : left_expr '=' right_expr 
                                 | left_expr '<' right_expr 
                 | left_expr '>' right_expr 
                 | left_expr '<=' right_expr 
                 | left_expr '>=' right_expr 
                 | right_expr '=' left_expr 
                 | right_expr '<' left_expr 
                 | right_expr '>' left_expr 
                 | right_expr '<=' left_expr 
                 | right_expr '>=' left_expr
                 | ...
right_expr : LITERAL | DYNAMIC_PARAM | CAST LITERAL
left_expr : COLUMN | cast_expr
cast_expr : CAST right_expr |  CAST left_expr 
 

谓词分解

将谓词分解为等值查询,范围查询,剩余查询三种类型

type = 'famliy' and  score < 60 and score >=0

Wquery=Pequal^Prange^Presidual

 

Pequal :  type = 'famliy'

Prange :  score < 60

 

而索引谓词分析的目标则是提取Pequal或者Prange

对于相同的字段,为了减少扫描范围,显然Pequal总是比Prange更优

 

一些规约

Pequal^Prange→Pequal

Pequal^Prange^Presidual→Pequal

Pequal^Presidual→Pequal

Prange^Presidual→Prange

 

索引最左匹配原则

做左到右尽可能扫描指定的运算符,遇到不是需要的运算符则停止扫描

分解点查询谓词节点

应用索引最左匹配原则(做左到右尽可能扫描=的条件),检查是否点查询并把它们转换成点查询条件组,即可下推索引谓词组,而不能转换的谓词节点构成剩余条件组.

分解范围查询谓词节点

 与分解点查询谓词节点相似,范围查询也是应用索引最左匹配原则(做左到右尽可能扫描>=,>等条件),检查是否点查询并把它们转换成上界/下界条件组,即可下推索引谓词组,而不能转换的谓词节点构成剩余条件组.这里的上下界条件组中每个条件不具有between语义.上界与下界是独立的条件.

score < 60 and score >=0 → [{score <60},{score >= 0}]

注解选择索引结果

 最后,可能得到一组索引信息分析得到的结果,如果谓词分析器带有了注解要求的索引,在结果中有,则返回它的索引结果.(所以错误的注解可能导致无法使用真正有效的索引)

最终的索引分析结果

 对它们的权重进行排序,返回权重最高的索引信息.

索引结果转换至分片条件

 每个索引谓词都有它们的类型,比如点查询或者范围查询.对于点查询,可以直接调用分片算法的点查接口就可以得到存储节点的信息.而对于范围查询,我们可以检查上界下界条件,并进一步把它们转换成查询区间,然后调用分片算法的范围查询接口即可.

键的优先级

 索引结果可能存在以下情况

 一个索引结果有多个不同的字段

 多个索引结果,这里仅讨论多个索引结果之间如何挑选最优的.

 如果一个谓词中出现多个字段,而这些字段中有多个是可以定位数据分布,但是它们的执行代价,扫描范围可能相同也可能不相同,有些需要额外的IO,连接才可以完成数据定位.这个情况下,我们需要定义这些定位数据分布的索引字段之间的优先级,从中选择最有效的字段来定位数据.一般来说,存在以下规则.

 

 等值查询总是比范围查询更优

 分表键总是比分库键更优

 

...

对于难以判断那种索引更优或者索引性能随着数据量改变的情况,可以使用代价分析判断.

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值