mysql - MySQL 查询说明:当查询有“WHERE”和“ORDER BY”时选择索引
问题描述
当我尝试使用索引优化查询时,有些事情我无法理解。
该表如下所示:
create table order_table (
id int not null primary key,
customer_id varchar(50) not null,
sale int not null,
key customer_sale_idx (customer_id, sale)
);
当我跑步时explain select * from order_table where customer_id=2 order by sale limit 1;
表明
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_table
partitions: NULL
type: index
possible_keys: customer_sale_idx
key: customer_sale_idx
key_len: 206
ref: NULL
rows: 5
filtered: 20.00
Extra: Using where; Using index; Using filesort
然后我添加另一个索引alter table order_table add key sale_customer_idx (sale, customer_id);
现在explain select * from order_table where customer_id=2 order by sale limit 1;
查询显示
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: order_table
partitions: NULL
type: index
possible_keys: customer_sale_idx
key: sale_customer_idx
key_len: 206
ref: NULL
rows: 1
filtered: 20.00
Extra: Using where; Using index
Q1:我想mysql应该先检查customer_id
,得到那些匹配的记录where
,然后做sort
by sale
。它customer_sale_idx
按照我的预期使用索引,但我不知道为什么它使用Using filesort
而不是使用封面索引
(customer_id, sale)
来进行排序。
sale_customer_idx (sale, customer_id)
Q2: MySQL 使用我添加后的新索引。但我不明白这个索引如何帮助摆脱Using filesort
.
Q3:后者explain
说只有一个possible_keys
是customer_sale_idx
,但后来它使用sale_customer_idx
。如何?
顺便说一句,我知道这很customer_id
奇怪varchar
。但让我们只专注于解释这种现象。
解决方案
看起来该表中的行数很少。对于非常小的表,表扫描和排序操作可能比索引扫描便宜。一旦你有几千行,执行计划将更加可预测。
推荐阅读
- python - 在主函数中使用 tf.Session()
- html - 如何创建一个 Angular 2+ *ngFor 填充表,每个单元格都有一条记录?
- javascript - 添加对将文本转换为 html 的支持
- hadoop - 从 hbase shell 调用 java 方法
- arrays - 在 Typescript 中使用 push 函数之前过滤对象数组
- nginx - 具有私有 IP 的 Kubernetes 入口控制器
- python - 为什么我的 python 2.7 代码中出现此字符串错误
- python - 将 Pandas 日期时间列(带时间戳)设置为仅显示凌晨 3 点之前的行
- java - Elasticsearch Springboot 集成测试
- vba - Excel - 从不同工作表和超链接上的单元格中提取数据