mysql - MySQL 索引 + 数学运算符
问题描述
我有评级表:
UserID int,
Rating int,
BanMask int,
index rating_index (Rating DESC),
index ban_index (BanMask ASC)
假设该表中有超过 500 万行,并且只有大约 100 个真正被禁止的用户。
如果我对索引字段使用位数学运算,选择查询是否仍会得到优化?这 2 个查询会使用索引优化吗?
SELECT * FROM ProfileTable
WHERE BanMask > 0
ORDER BY Rating DESC LIMIT 10;
对比
SELECT * FromProfileTable
WHERE (BanMask & (1 << 2)) > 0
ORDER BY Rating DESC LIMIT 10;
第二个问题。我应该在 Rating + BanMask 字段上添加索引以获得更好的优化吗?像这样:
CREATE INDEX rating_ban_index ON ProfileTable (Rating DESC, BanMask ASC)
解决方案
您可以使用EXPLAIN自己确认哪些索引用于给定查询。
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: RatingTable
type: index
possible_keys: ban_index
key: rating_index
key_len: 5
ref: NULL
rows: 10
Extra: Using where
您应该研究此手册页以获取对输出的解释:https ://dev.mysql.com/doc/refman/8.0/en/explain-output.html
我希望没有索引可以用于使用表达式的查询。
WHERE (BanMask & (1 << 2)) > 0
EXPLAIN 报告显示:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: RatingTable
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra: Using where; Using filesort
通常,如果比较运算符左侧的索引列在表达式或函数中被引用,则不能使用索引。它必须是“裸”列。
当您搜索按索引的排序顺序排列在一起的值时,索引会起作用。您的示例搜索 BanMask 中的每 4 个值,即那些在 4 的位置集中具有该位的值。这些值不是连续的,它们是分散的。MySQL 不会使用索引来搜索整个值的范围,因为最终这将与扫描整个表一样昂贵。
至于你的第二个问题,关于在 上添加索引(Rating DESC, BanMask ASC)
,答案是它可能有助于避免文件排序。但它无助于搜索 BanMask。
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: RatingTable
partitions: NULL
type: index
possible_keys: NULL
key: Rating
key_len: 10
ref: NULL
rows: 10
Extra: Using where
推荐阅读
- e-commerce - Shopify 产品图片无法点击
- solr - Solr error - Stream Body is disabled
- java - 在 Call 级别改造 2 + 拦截器
- pandas - 如何更新我的 unnesting python 功能以包含没有选项的产品?
- excel - 如何提取带有特定文本的 URL?
- javascript - HTML 弹出框修复
- windows - 知道驱动器上是否使用了 bitlocker 或 bitlocker togo
- javadoc - Javadoc:使用默认参数链接到方法
- azure - 从 Azure 传出连接的 SNAT 端口(堆栈)
- arrays - 在数组中找不到字符串值