我认为 MySQL 使用了错误的索引

标签 mysql indexing

这是我的 table :

- user_id INT (foreign key on `user` with the reference `id`)
- question_id INT (foreign key on `question` with the reference `id`)
- option_id INT (foreign key on `option` with the reference `id`)
- exam_id INT (foreign key on `exam` with the reference `id`)
- order INT

我的索引是:user_id, exam_id

我的查询:

select * from `user_answer` where `user_id` = '48' and `exam_id` = '1' and `order` > '10' order by `order` desc limit 1;

我认为它应该使用我的索引,但这是EXPLAIN的结果:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'user_answer', 'range', 'user_answer_exam_id_foreign,user_answer_user_id_exam_id_index', 'user_answer_exam_id_foreign', '4', NULL, '10', 'Using where; Using filesort'

显然,它没有使用我的索引。当我使用FORCE INDEX时:

select * from `user_answer` force index (user_answer_user_id_exam_id_index) where `user_id` = '48' and `exam_id` = '1' and `order` > '10' order by `order` desc limit 1;

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
'1', 'SIMPLE', 'user_answer', 'ref', 'user_answer_user_id_exam_id_index', 'user_answer_user_id_exam_id_index', '8', 'const,const', '10', 'Using where; Using filesort'

知道我或 MySQL 出了什么问题吗?

最佳答案

MySQL 将忽略那些不会大幅缩小结果范围的索引。

作为一个非常粗略的经验法则,如果索引没有将行数减少到大约 1/3 以下,那么它将被忽略(这非常粗略,但给了您一个想法)。即,如果您有 100 条记录,而索引仅将其范围缩小到约 40 条,那么 MySQL 可能会忽略该索引。单独检查每一行比使用索引更快。

令人烦恼的是,即使它选择不使用其他有效的索引,它仍然暂时使用索引在慢查询日志上报告查询!

关于我认为 MySQL 使用了错误的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23741144/

相关文章:

mysql - 日期编码问题

mysql - mysql 存储和搜索字符串的最佳实践

database - 根据前缀在表中查找单词

c# - 在 Entity Framework 中使用 SqlQuery RAW 查询返回匿名类型

mysql - 为每个日期选择行的子集

MySQL 部分字段加密

Java - 单击 JButton 将 int 值更改为特定范围内的随机数

ruby-on-rails - 使用 2 列之间的差异加速数据库查询 : created_at and updated_at

java - 握手期间通信失败。本地主机 :3306 上是否有运行 MySQL 服务器

mysql - 从列中检索条目并与同一列中的其他条目进行比较