关于查询排序后分页的索引

数据库如果排序的话会需要先物化整个结果集,有时候合适的索引可以避免物化整个结果集。
下边我们举例说明。

表a如下:

idnameagesexcreated_at
1李一一302018-09-01 12:36:50
2张三412018-09-02 12:36:50
3小明302018-09-05 12:36:50
4李磊512018-09-01 12:06:50
5韩梅梅302018-09-01 12:26:50
6啥啥啥412018-09-01 12:36:40
7想不起来了402018-09-01 15:36:50
8你好312018-09-10 15:36:50
9恭喜发财302018-09-01 12:36:45
10阖家欢乐302018-09-01 12:39:50

我们看这个查询

select * from a where a.age=3 order by created_at limit 2;

当执行查询时候
如果表中有索引age,索引大约是这个样子(内部实现未研究,只是写大概

age数据所在地址(这里有表a的id代替)
3[1,3,5,8,9,10]
4[2,6,7]
5[4]

那么数据库需要提起age=3的数据,虽然我们只需要两条,但是由于需要根据created_at进行排序,那么数据库就不得不将age=3的数据全部提取,然后进行排序,接着取符合条件的两条数据,也就是说数据库实际读取的数据是6条,如果符合条件的数据有很多,那么提取所有数据然后排序这个时间将不可忽略。

那么我们可不可以让数据库直接提取两条数据结束查询呢?

这时候我们可以创建联合索引age,created_at
那么索引的内容大约是这样子的:
在这里插入图片描述
在索引中,查询到age=3之后,直接顺序或倒叙查询,去除符合条件的两条数据即可。避免了取出全部数据和排序。当数据量大时,可以节省查询时间。

缺点

查询条件age不能使用区间类的,比如

select * from a where age>2 and age<5 order by created_at limit 2;

查询时仍需要提取所有符合条件的数据,然后排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值