descending indexes
descending indexes 要解决的问题
descending indexes (倒排索引) 是为了让 order by xxx desc 执行的更加快而开发的新特性。
实验环境
表结构和数据量如下。
mysql> show create table t;
+------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`id` int NOT NULL AUTO_INCREMENT,
`i0` int NOT NULL DEFAULT '0',
`i1` int NOT NULL,
`i2` int NOT NULL,
`i3` int NOT NULL,
`c0` varchar(128) NOT NULL,
`c1` varchar(128) NOT NULL,
`f0` float NOT NULL,
`f1` float NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_i012` (`i0`,`i1`,`i2`),
) ENGINE=InnoDB AUTO_INCREMENT=1120001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
| 1120000 |
+----------+
1 row in set (0.94 sec)
使用非倒排索引的情况
执行计划和实际执行耗时如下。
mysql> explain select i0,i3 from t where i0=1 order by i0,i1 desc;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+-------+----------+---------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+-------+----------+---------------------+
| 1 | SIMPLE | t | NULL | ref | idx_i012 | idx_i012 | 4 | const | 21374 | 100.00 | Backward index scan |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+-------+----------+---------------------+
1 row in set, 1 warning (0.00 sec)
mysql> select i0,i3 from t where i0=1 order by i0,i1 desc;
11200 rows in set (2.29 sec)
使用倒排索引的情况
执行计划和实际执行耗时如下。
-- 添加倒排索引(i1 desc)
alter table t add index ixd_0_desc1(i0,i1 desc);
mysql> explain select i0,i3 from t where i0=1 order by i0,i1 desc;
+----+-------------+-------+------------+------+----------------------+-------------+---------+-------+-------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+----------------------+-------------+---------+-------+-------+----------+-------+
| 1 | SIMPLE | t | NULL | ref | idx_i012,ixd_0_desc1 | ixd_0_desc1 | 4 | const | 20864 | 100.00 | NULL |
+----+-------------+-------+------------+------+----------------------+-------------+---------+-------+-------+----------+-------+
1 row in set, 1 warning (0.00 sec)
mysql> explain select i0,i3 from t where i0=1 order by i0,i1 desc;
11200 rows in set (0.82 sec)
结论
在当前的场景下使用倒排索引可以把耗时从 2.29s 降到 0.82s ,大致提升 3 倍性能。