专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
蚂蚁技术AntTech  ·  蚂蚁百灵大模型:智能演进与开源实践 ·  15 小时前  
程序员的那些事  ·  黄仁勋回应任正非最新讲话 ·  3 天前  
程序员的那些事  ·  GitHub 第 10 ... ·  3 天前  
阿里云云栖号  ·  2025阿里云中企出海峰会·深圳,6月24日见! ·  2 天前  
稀土掘金技术社区  ·  探索 Ant Design Form ... ·  昨天  
51好读  ›  专栏  ›  OSC开源社区

美团开源 SQL 优化工具 SQLAdvisor,与内部版本保持一致

OSC开源社区  · 公众号  · 程序员  · 2017-03-11 08:30

正文

请到「今天看啥」查看全文


  • 支持常见的 SQL(Insert/Delete/Update/Select);

  • 支持多表 Join 并自动逻辑选定驱动表;

  • 支持聚合条件 Order by 和 Group by;

  • 过滤表中已存在的索引。


  • SQLAdvisor 原理介绍


    Join 处理

    1. Join语法分为两种:Join on 和 Join using,且 Join on 有时会存在 where 条件中。

    2. 分析 Join 条件首先会得到一个 nested_join 的 table list,通过判断它 join_using_fields 字段是否为空来区分 Join on 与 Join using。

    3. 生成的 table list 以二叉树的形式进行存储,以后序遍历的方式对二叉树进行遍历。

    4. 生成内部解析树时,right Join 会转换成 left Join。

    5. Join 条件会存在当层的叶子节点上,如果左右节点都是叶子节点,会存在右叶子节点。

    6. 每一个非叶子节点代表一次 Join 的结果。

    上述实现时,涉及的函数为:mysql_sql_parse_join(TABLE_LIST join_table) mysql_sql_parse_join(Item join_condition) ,主要流程图如下:

    where 处理

    1. 主要是提取 SQL 语句的 where 条件。where 条件中一般由 AND 和 OR 连接符进行连接,因为 OR 比较难以处理,所以忽略,只处理 AND 连接符。

    2. 由于 where 条件中可以存在 Join 条件,因此需要进行区分。

    3. 依次获取 where 条件,当条件中的操作符是 like,如果不是前缀匹配则丢弃这个条件。

    4. 根据条件计算字段的区分度按照高低进行倒序排,如果小于30则丢弃。同时使用最左原则将 where 条件进行有序排列。

    计算区分度

    1. 通过 “show table status like” 获得表的总行数 table_count。

    2. 通过计算选择表中已存在的区分度最高的索引 best_index,同时Primary key > Unique key > 一般索引。

    3. 通过计算获取数据采样的起始值offset与采样范围rand_rows:

    • offset = (table_count / 2) > 10W ? 10W : (table_count / 2)

    • rand_rows =(table_count / 2) > 1W ? 1W : (table_count / 2)

    • 使用select count(1) from (select field from table force index(best_index) order by cl.. desc limit rand_rows) where field_print 得到满足条件的rows。







    请到「今天看啥」查看全文