这一章主要涉及TiDB如下的源码:

  1. 扫表算子怎样转换为扫索引算子;

  2. 怎样把Selection算子的过滤条件化简, 转为区间扫描;

假设我们有一个表:

t1(
  id int primary key not null auto_increment,
  a int,
  b int,
  c varchar(),
  index(a)
);

其中, id 是主键, a 是索引;

我们执行如下的 sql:

select a from t1 where a= or ( a> and (a> and a <)  and a<);

这条 sql 的最终执行计划是这样的:

+---------------+--------+-----------+-----------------------------------------------------------------------+
| id | count | task | operator info |
+---------------+--------+-----------+-----------------------------------------------------------------------+
| IndexReader_6 | 260.00 | root | index:IndexScan_5 |
| └─IndexScan_5 | 260.00 | cop[tikv] | table:t1, index:a, range:[5,5], (6,8), keep order:false, stats:pseudo |
+---------------+--------+-----------+-----------------------------------------------------------------------+  

这是一个索引扫描的执行计划, 索引扫描区间是 [5,5], (6,8);

我们转到源代码, 看这样的计划是怎样生成的;

这是解析 sql 之后最初生成的执行计划:

在调用 logicalOptimize 函数做逻辑优化之后, 执行计划变为下面这样:

Selection算子哪儿去了?

Selection算子被下推到了 DataSource 算子中, 在 DataSource 的 pushedDownConds 中保存着下推的过滤算子, 是这样的:

这样的一个递归的树状的过滤算子很难在索引扫描中使用, 因为索引底层是顺序排列的, 所以要将这颗树转为扫描区间;

在物理优化中, 会调用 DetachCondAndBuildRangeForIndex 来生成扫描区间, 这个函数会递归的调用如下 2 个函数:

detachDNFCondAndBuildRangeForIndex, 展开 析取范式(DNF), 生成扫描区间或合并扫描区间;
detachCNFCondAndBuildRangeForIndex, 展开 合取范式(CNF), 生成扫描区间或合并扫描区间;

上面的表达式树最终生成了这样的区间: [5,5], (6,8) --- "[" 是开区间, "(" 是闭区间,  递归被消除了;

接下来, 这个索引扫描会加入到 DataSource 的备选的访问表的方法中;

在 DataSource 的 possibleAccessPaths 里保存了访问表的可能的方案, 这里是 2 个方案:

  1. 全表扫描, 用表达式树进行过滤: a=5 or ( a>5 and (a>6 and a <8) and a<12);

  2. 扫索引 a 列, 执行区间扫描 [5,5], (6,8);

物理优化阶段, 会从算子树的根节点递归调用每个算子的 findBestTask 函数, DataSoure 算子会从 possibleAccessPaths  获取最优的执行计划;

这里用到了 skyline pruning 算法, 从多个维度来判断哪个执行计划更优, 最后用索引扫描算子替换掉 DataSource 算子;

最终生成了这样的执行计划:

结束;

												

肤浅的聊聊 TiDB 扫表算子, 扫索引算子, 合取范式(CNF), 析取范式(DNF), skyline pruning的更多相关文章

  1. 肤浅的聊聊关联子查询,数据集连接,TiDB代码,关系代数,等等

    本章涉及的内容是TiDB的计算层代码,就是我们编译完 TiDB 后在bin目录下生成的 tidb-server 的可执行文件,它是用 go 实现的,里面对 TiPD 和 TiKV实现了Mock,可以单 ...

  2. 简单聊聊TiDB中sql优化的一个规则---左连接消除(Left Out Join Elimination)

    我们看看 TiDB 一段代码的实现 --- 左外连接(Left Out Join)的消除; select 的优化一般是这样的过程: 在逻辑执行计划的优化阶段, 会有很多关系代数的规则, 需要将逻辑执行 ...

  3. 隔行扫瞄/逐行扫瞄的介绍(Interlaced / Progressive)

    隔行扫瞄/逐行扫瞄的介绍(Interlaced / Progressive)   本篇不是着重在理论说明, 而是实际验証结果的分享, 所以只简略解释何谓交错与非交错, 请参考如后. 交错扫瞄(隔行扫瞄 ...

  4. 关于数据库表中的索引及索引列的CRUD

     -- 查询一个数据库表中的索引及索引列use [RuPengWangDB]GOSELECT  indexname = a.name , tablename = c. name , indexcolu ...

  5. 无法重新组织表 "ty_wf_ex_local_process_info" 的索引 "idx_prc_act_id" (分区 1),因为已禁用页级锁定。

    无法重新组织表 "ty_wf_ex_local_process_info" 的索引 "idx_prc_act_id" (分区 1),因为已禁用页级锁定. ALT ...

  6. Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题

    Mysql数据库表排序规则不一致导致联表查询,索引不起作用问题 表更描述: 将mysql数据库中的worktask表添加ishaspic字段. 具体操作:(1)数据库worktask表新添是否有图片字 ...

  7. SQL优化的四个方面,缓存,表结构,索引,SQL语句

    一,缓存 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所 ...

  8. 单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式

    单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式     一 表结构如下:  万行 CREATE TABLE t_audit_operate_log (  Fid b ...

  9. SQL Server 查看指定表上的索引

    解决方案: sys.indexs; ---------------------------------------------------------------------------------- ...

随机推荐

  1. FireDAC 中文字段过滤问题

    当使用 FireDAC Filter  过滤数据的时候,通常这样写: FDMemTable.Filtered := False; FDMemTable1.Filter := '姓名=' + strin ...

  2. 永久修改 Linux pip国内源

    一些常用的国内源 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple 阿里云:https://mirrors.aliyun.com/pypi/simple 中国 ...

  3. 40 多线程(十二)——ReentrantLock 可重入锁

    我们使用的synchronized加的锁是可以延续使用的,如下: public void test() { //第一次获得锁 synchronized(this) { while(true) { // ...

  4. Linux组管理、用户管理、查看用户信息、usermod、which、切换用户、修改文件具体权限

    组管理 提示:创建组/删除组的终端命令都需要通过sudo执行 序号 命令 作用 01 groupadd组名 添加组 02 groupdel组名 删除组 03 cat/etc/group 确认组信息 0 ...

  5. 登陆并访问k8s的apiserver

    kubeadm安装的k8s集群默认需要用户登陆认证,无法直接使用命令curl访问.所以首先的第一步就是获取token. 先找到k8s集群中的dns组件coredns,之前的版本使用的是kube-dns ...

  6. Spring Cloud Alibaba学习笔记(18) - Spring Cloud Gateway 内置的过滤器工厂

    参考:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.1.0.RELEASE/single/spring-clou ...

  7. ActiveMQ(一)

    下载地址:http://activemq.apache.org/download.html 换数据源: ActiveMQ的独占消费

  8. Spring主要用到两种设计模式

    Spring主要用到两种设计模式 1.工厂模式 Spring容器就是实例化和管理全部Bean的工厂. 工厂模式可以将Java对象的调用者从被调用者的实现逻辑中分离出来. 调用者只关心被调用者必须满足的 ...

  9. python3--说简单也不简单的排序算法

    在刚开始接触算法时,我们可能一脸懵,不知从何处下手,尤其是现在使用的语言五花八门,各种语言的实现又不尽相同,所以,在这种情况下,千万不能迷失了自己,掌握了算法的原理,就像解数学公式一样,定理给你了,仔 ...

  10. “proxy” in package.json must be a string 解决办法

    今天学习一个react项目.想从本地服务器获取数据. 直接axios.get('http://localhost:80/api/react/header.json'),报错跨域. 网上查了下,需要在p ...