[英]Why order by clause can make use of index?
Assume in tableX
we have id
(primary key) name
and age
, phone
, all with indices.假设在
tableX
中我们有id
(主键) name
和age
, phone
,都有索引。
In this query: select phone from tableX where name='Dennis' order by age
在此查询中:
select phone from tableX where name='Dennis' order by age
I guess the process is我猜过程是
Using name
index to get ids that match Dennis
.使用
name
索引获取与Dennis
匹配的 ID。 Denote the id set by S
表示
S
设置的id
Use age
index to do order by on the ids obtained in 1, get a sorted id list, denoted by L
用
age
索引对1中得到的ids做order by,得到一个排序好的id列表,记为L
Use the sorted id list L
to get phone
使用排序后的 id 列表
L
获取phone
I assume in step 2 it may use a sequential scan along the B+ tree leaf nodes, checking whether the id in that leaf node is in the id set S
obtained in step 1. If so, add it into list L
, then we can get a id list L
sorted by age
.我假设在步骤 2 中它可能使用沿 B+ 树叶节点的顺序扫描,检查该叶节点中的 id 是否在步骤 1 中获得的 id 集合
S
中。如果是,将其添加到列表L
中,然后我们可以得到按age
排序的 id 列表L
But how is that better than simple sequential scan?但这比简单的顺序扫描好在哪里呢? Aren't they both sequential scan?
他们不是都是顺序扫描吗?
Edit:编辑:
explain
says it uses index name
and does a filesort
explain
说它使用索引name
并进行filesort
+----+-------------+--------+------------+------+---------------+----------+---------+-------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+----------+---------+-------+------+----------+----------------+
| 1 | SIMPLE | tableX | NULL | ref | idx_name | idx_name | 123 | const | 1 | 100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+----------+---------+-------+------+----------+----------------+
Actually I was not sure in what situation index can be useful in order by
clause, so I came up with a bad example to illustrate my doubt.实际上我不确定索引在什么情况下可以用于
order by
子句,所以我想出了一个不好的例子来说明我的疑问。
But the example provided by Tim Biegeleisen is great.但是 Tim Biegeleisen 提供的示例非常棒。
(More table details if you are interested:) (如果您有兴趣,请查看更多表格详情:)
mysql> create table tableX(
-> id int primary key,
-> name varchar(30),
-> age int,
-> phone varchar(30)
-> );
Query OK, 0 rows affected (0.07 sec)
mysql> create index idx_name on tableX(name);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create index idx_age on tableX(age);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> create index idx_phone on tableX(phone);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from tableX;
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| tableX | 0 | PRIMARY | 1 | id | A | 1 | NULL | NULL | | BTREE | | | YES | NULL |
| tableX | 1 | idx_name | 1 | name | A | 1 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tableX | 1 | idx_age | 1 | age | A | 1 | NULL | NULL | YES | BTREE | | | YES | NULL |
| tableX | 1 | idx_phone | 1 | phone | A | 1 | NULL | NULL | YES | BTREE | | | YES | NULL |
+--------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.01 sec)
mysql> select * from tableX;
+----+--------+------+-------+
| id | name | age | phone |
+----+--------+------+-------+
| 1 | Jack | 20 | 180 |
| 2 | Dennis | 22 | 180 |
| 3 | Dennis | 18 | 1790 |
+----+--------+------+-------+
Actually, the index which should help here is a compound one:实际上,应该在这里提供帮助的索引是一个复合索引:
CREATE INDEX idx ON tableX (name, age, phone)
The above index, if used, would likely have the following steps:如果使用上述索引,可能会有以下步骤:
phone
column making this a covering index for the query;phone
列,使其成为查询的覆盖索引; all the columns it needs can be read directly from the index.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.