mysql 大数据量高效分页查询

时间:2021-06-30 11:31:35
像select * from user where xx=1 limit 10,10这样的查询在大数据量下查询比较低效,请问有没有高效的方法呢?
最好说明一下原理,谢谢哈!(ps:只是用简单的数据库查询不用存储过程的)

8 个解决方案

#1


yueliangdao0608有编文章,专门讲这个的。

#2


最好能 用上索引字段
假设在ID上有索引
select * from tt a inner join ( 
select id from tt order by id limit 10,10) b
on a.id=b.id

#3


http://willko.javaeye.com/blog/325618
http://willko.javaeye.com/blog/670120
优化limit和offset 
MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要的,所以n越大,性能会越差。 
优化前SQL: SELECT * FROM member ORDER BY last_active LIMIT 50,5 
优化后SQL: SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5) USING (member_id) 
分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。 

#4


其实你可以去查看一下一些大型的交友网站,你会发现他们的搜索结果始终是一固定的页数(当然这也是建立在大数据量的情况下),它会把当前你搜索的所有结果保存到某一位置,如数据库,MEMCACHE.........,然后利用这些数据再进行分页,这样分页的记录相对来说就会少很多
其实对于大数据量的分页,你给他一个几十页的数据浏览,已经够了,没必要每次分页都去源数据库,不停的找,前几页还好,愈往后查询效率肯定也会慢慢变差,所以来说,建立一个空间保存搜索结果比较合适,不过还是看你是否真的有大数据量
如果只是上百万数据量的分页,也没太必要使用上面的方式,你只要在某个时间段内保存搜索的总记录数,这样避免了每次去搜索时还得去搜索总记录数的二次开销,再建立正确的索引,搜索速度还是可以接受的

#5


select * from user where xx=1 limit 10,10

你需要有ORDER BY 字段。 然后需要 (xx, orderCol) 的复合索引,再使用

select * from user a inner join (select id from user where xx=1 order by id limit 10,10) b using(id)

#6


谢谢大家,大致明白了“分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。”这个说得挺明白的,欢迎继续讨论哈!

#7


我顶一下.................

#8


有用..............

#1


yueliangdao0608有编文章,专门讲这个的。

#2


最好能 用上索引字段
假设在ID上有索引
select * from tt a inner join ( 
select id from tt order by id limit 10,10) b
on a.id=b.id

#3


http://willko.javaeye.com/blog/325618
http://willko.javaeye.com/blog/670120
优化limit和offset 
MySQL的limit工作原理就是先读取n条记录,然后抛弃前n条,读m条想要的,所以n越大,性能会越差。 
优化前SQL: SELECT * FROM member ORDER BY last_active LIMIT 50,5 
优化后SQL: SELECT * FROM member INNER JOIN (SELECT member_id FROM member ORDER BY last_active LIMIT 50, 5) USING (member_id) 
分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。 

#4


其实你可以去查看一下一些大型的交友网站,你会发现他们的搜索结果始终是一固定的页数(当然这也是建立在大数据量的情况下),它会把当前你搜索的所有结果保存到某一位置,如数据库,MEMCACHE.........,然后利用这些数据再进行分页,这样分页的记录相对来说就会少很多
其实对于大数据量的分页,你给他一个几十页的数据浏览,已经够了,没必要每次分页都去源数据库,不停的找,前几页还好,愈往后查询效率肯定也会慢慢变差,所以来说,建立一个空间保存搜索结果比较合适,不过还是看你是否真的有大数据量
如果只是上百万数据量的分页,也没太必要使用上面的方式,你只要在某个时间段内保存搜索的总记录数,这样避免了每次去搜索时还得去搜索总记录数的二次开销,再建立正确的索引,搜索速度还是可以接受的

#5


select * from user where xx=1 limit 10,10

你需要有ORDER BY 字段。 然后需要 (xx, orderCol) 的复合索引,再使用

select * from user a inner join (select id from user where xx=1 order by id limit 10,10) b using(id)

#6


谢谢大家,大致明白了“分别在于,优化前的SQL需要更多I/O浪费,因为先读索引,再读数据,然后抛弃无需的行。而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。”这个说得挺明白的,欢迎继续讨论哈!

#7


我顶一下.................

#8


有用..............