最好说明一下原理,谢谢哈!(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
假设在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读取需要的列。
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)
你需要有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
假设在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读取需要的列。
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)
你需要有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
有用..............