mysql - MySQL Btrees:当使用所有列时,基数和列顺序对复合索引是否重要?
问题描述
我很难弄清楚,所以让我问你。给定以下查询:
select name from users where company_id = ? and creation_date > ?
假设我们只有 2 家公司,每家公司都有数百万用户在不同的时刻创建。所以基数creation_date
要高得多。以下哪个索引更快,为什么?
- index_a(公司 ID,创建日期)
- index_b(创建日期,公司 ID)
- index_c(创建日期)
- index_d(company_id)
哪个指数更快(或理论上相等)?忽略磁盘空间使用,除非这会以某种方式影响读取性能。我的想法:
(index_b ~= index_c) > index_a > index_d
因为在 Btree 中,“时间戳”将被分组在一个区域中,因此提取会更早停止。实际上并不重要,company_id
因为数据库需要使用索引中的 ROWID 来触摸表行以name
获取SELECT
. 几乎没有区别。排在第二位index_a
的是在 BTREE 中将低基数值“组合”在一起,因此“b-search”需要一些时间通过限制搜索范围来显示其值creation_date
(在指数)。最后index_d
,由于明显的原因(基数为百万行中的 2),情况更糟。
额外问题:如果我们有 10kk 行,公司 A 和公司 B 有 5kk 行,两家公司平均分配 7kk 时间戳,而其他 3kk 完全不同的时间戳怎么办。7kk 范围内的搜索会比 3kk 范围内的搜索差得多吗?
那正确吗?我错过了什么?
(可视化算法的好地方:https ://www.cs.usfca.edu/~galles/visualization/BTree.html )
PS: StackOverflow 中有两个相互矛盾的答案:
解决方案
对于该特定查询, index_a 应该是最快的,因为结果与索引中的范围完全对应。
使用 index_b 或 index_c 比较慢。您必须获取有效日期的范围,然后过滤掉公司 ID 错误的行。在这两者中, index_c 较慢,因为您必须触摸过滤掉的行。
使用 index_d 是最慢的。您可以找到公司 ID 的范围,但必须扫描所有行以查找匹配日期。
推荐阅读
- server - 当前一代至强处理器之间的差异
- r - 避免从 blogdown::serve_site() 渲染特定的 .md 文件
- debugging - Windows 10 上 Delve for Go 中的代码显示问题
- variables - 帕斯卡 | 初始化变量
- java - 在处理和理解代码中创建可视化
- django - 在 Django 中显示来自模型对象的图像
- linux - 试图了解 wwan0 上传输的数据量?
- python - 打印 3D 网格搜索以实现超参数可视化
- javascript - JavaScript QuerySelector 不返回最后一个孩子
- wso2-am - 无法在 wso2-am 3.0 中更改 api-manager.xml