正文
支持常见的 SQL(Insert/Delete/Update/Select);
支持多表 Join 并自动逻辑选定驱动表;
支持聚合条件 Order by 和 Group by;
过滤表中已存在的索引。
Join 处理
-
Join语法分为两种:Join on 和 Join using,且 Join on 有时会存在 where 条件中。
-
分析 Join 条件首先会得到一个 nested_join 的 table list,通过判断它 join_using_fields 字段是否为空来区分 Join on 与 Join using。
-
生成的 table list 以二叉树的形式进行存储,以后序遍历的方式对二叉树进行遍历。
-
生成内部解析树时,right Join 会转换成 left Join。
-
Join 条件会存在当层的叶子节点上,如果左右节点都是叶子节点,会存在右叶子节点。
-
每一个非叶子节点代表一次 Join 的结果。
上述实现时,涉及的函数为:mysql_sql_parse_join(TABLE_LIST join_table) mysql_sql_parse_join(Item join_condition) ,主要流程图如下:
where 处理
-
主要是提取 SQL 语句的 where 条件。where 条件中一般由 AND 和 OR 连接符进行连接,因为 OR 比较难以处理,所以忽略,只处理 AND 连接符。
-
由于 where 条件中可以存在 Join 条件,因此需要进行区分。
-
依次获取 where 条件,当条件中的操作符是 like,如果不是前缀匹配则丢弃这个条件。
-
根据条件计算字段的区分度按照高低进行倒序排,如果小于30则丢弃。同时使用最左原则将 where 条件进行有序排列。
计算区分度
-
通过 “show table status like” 获得表的总行数 table_count。
-
通过计算选择表中已存在的区分度最高的索引 best_index,同时Primary key > Unique key > 一般索引。
-
通过计算获取数据采样的起始值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。