Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support MySQL index optimize #55

Closed
3 tasks done
sjjian opened this issue Nov 1, 2021 · 3 comments
Closed
3 tasks done

support MySQL index optimize #55

sjjian opened this issue Nov 1, 2021 · 3 comments
Assignees
Labels
Milestone

Comments

@sjjian
Copy link
Member

sjjian commented Nov 1, 2021

sub-task tracking:

@sjjian sjjian added the feature label Nov 1, 2021
@sjjian sjjian added this to the v1.2111.0 milestone Nov 1, 2021
@sjjian
Copy link
Member Author

sjjian commented Nov 1, 2021

需要考虑ce/ee功能区分

@drivebyer
Copy link
Contributor

drivebyer commented Nov 5, 2021

功能

交互

新增全局配置规则 ConfigIndexOptimizerEnabled,启用该规则表明会对 select 语句开启索引优化建议流程。该规则的 value 设计为 json 格式,支持的配置为:

{
    "ConfigIndexOptimizerCalcSelectivityMaxRow": 10000000,
    "ConfigIndexOptimizerCompositeIndexesMaxColumn": 3,
}
  1. ConfigIndexOptimizerCalcSelectivityMaxRow(默认值 10000000):当表行数高于阈值时,不计算列的可选择性(selectivity)。计算列的可选择性,是为了给出联合索引的最佳列顺序。这个配置的目的是为了保护数据库,当表的数据量太大时,执行 sleect count(distinnct) 可能对数据库造成压力。
  2. ConfigIndexOptimizerCompositeIndexesMaxColumn(默认值 3):联合索引列数不能超过阈值。

当用户启用规则 ConfigIndexOptimizerEnabled 后,在工单页面在输入 select 语句,点击审核,在「审核结果」中会给出审核结果等级为 notice 的索引建议。

索引建议支持场景:

等值查询

SQL:select * from t1 where c1 = '1';
索引建议:建议给表 t1 列 c1 添加索引。原因:三星索引建议

SQL:select * from t1 where c1 = '1' and c2 = '2' and c3 > '3'; selectivity(c2) > selectivity(c1)
索引建议:建议给表 t1 列 c2, c1 按顺序添加索引。原因:三星索引建议。

SQL:select c1,c2,c3 from t1 where c1 = '1'; selectivity(c3) > selectivity(c2)
索引建议:建议给表 t1 列 c1,c3,c2 按顺序添加索引。原因:三星索引建议。

模糊查询

SQL:select * from t1 where c1 like 'abcdef%';
索引建议:建议给表 t1 列 c1 添加索引。原因:为前缀模式匹配添加前缀索引。

关联查询

SQL:select * from t1, t2 where t1.c1 = t2.c1; rows(t1) > rows(t2)
索引建议:建议给表 t1 列 c1 添加索引。原因:t1 结果集较大,为被驱动表。

函数查询

SQL:select * from t1 where date(c1) = '2100-02-02';
建议:建议给表 t1 列 c1 添加函数索引。原因:MySQL 版本高于 8.0.13,可以直接创建函数索引。

SQL:select * from t1 where date(c1) = '2100-02-02';
建议:建议给表 t1 添加虚拟列,并在虚拟列上创建索引。原因:MySQL 版本低于 8.0.13。

SQL:select Min(c1) from t1;
建议:建议给表 t1 列 c1 索引。原因:利用索引有序的性质快速找到记录。

考虑

  1. 查询字段顺序与索引顺序保持一致?
  2. 范围查询结果集与实际结果集比较,判断走二级索引还是聚簇索引
  3. 从优化 SQL 的角度,参考 DBLE SQL 改写

@drivebyer
Copy link
Contributor

drivebyer commented Dec 5, 2021

方案:
流程如下:
sqle-index-optimization

整体目标是将不同类型数据库公用的逻辑抽离出来,形成 three-star index 算法。在此基础上针对不同的数据库有自己 case-by-case 的逻辑。

  1. 等值查询时:使用 three-star index 算法(参考《Relational database index design and the optimizers》第四章)作为多数据库类型的索引建议通用方案(three-star index 算法只对单表查询给出索引建议)
  2. 多表关联查询时:结合 explain 找到被驱动表,对被驱动表的关联字段添加索引
  3. 模糊查询和函数查询时:走 「do MySQL specified optimization」 逻辑

对数据库下发的 SQL:

  1. 开启索引优化则会下发 explain 语句
    2.使用 show table status 查看表行数
    3.使用 select count(distinct ) 计算列的基数(只有表行数低于配置值时才会下发此 SQL)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants