在自己的笔记本上,使用docker启动8.0.33版本的mysql镜像。
100w的数据量,没必要优化(索引都不需要加),单表不管怎么查,都是1秒内。
1000w的量级才需要优化
表结构:
CREATE TABLE `p_1000w` (
`id` bigint NOT NULL AUTO_INCREMENT,
`age` int DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`status` int DEFAULT '0',
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_ct` (`create_time`)
) ENGINE=InnoDB AUTO_INCREMENT=12124966 DEFAULT CHARSET=utf8mb4
如果没有索引,10万的排序偏移需要7秒多,加上索引后可以到1秒内。
select * from p_1000w force index(idx_ct)
order by create_time desc
limit 100000, 10
需要force index(idx_ct)
才能走索引,有点撒贝。
如果是百万的排序偏移,光依赖索引也很慢。100万8秒多,900万70多秒。
需要使用覆盖索引优化。
select * from p_1000w where id in (
select id from (
select id from p_1000w # 这条sql去掉force index也知道走索引
order by create_time desc
limit 9000000, 10) as temp
)
order by create_time desc
2秒内搞定。之所以快这么多,是因为减少了大量不需要的回表操作,而mysql使用的不是堆表,所以回表的效率更低(数据库之堆表和索引组织表)。
为什么不直接:
select * from p_1000w where id in (
select id from p_1000w
order by create_time desc
limit 9000000, 10
)
order by create_time desc
因为撒贝mysql,子查询不支持使用limit。
网友评论