1、避免count(*)
不用显示所有消息数量,可让用户通过点击next获取更多消息
不要为每个请求计算count,缓存count,不用显示太精确的count值,用户不会太关心
可按不同数量级,显示不同精度的count
事先计算好count,随着insert/delete操作增加/减少count
2、避免在limit中使用offset
不要让用户直接跳转到第N页
尽可能使用limit N,不要使用Limit M, N
在请求中包含请求页的起始位置
使用请求中包含的查询条件结合order by和limit N,构造严格的where语句,找到期望的记录
3、非唯一索引键排序时,可用另外一列作为次要查询条件,或者主要和次要查询列联合作为查询条件,比如可以使用primary id
例子1:
Next Page:
http://domain.com/forum?page=2&last_seen=100&dir=next
WHERE id < 100 /* last_seen */
ORDER BY id DESC LIMIT $page_size /* No OFFSET*/
Prev Page:
http://domain.com/forum?page=1&last_seen=98&dir=prev
WHERE id > 98 /* last_seen */
ORDER BY id ASC LIMIT $page_size /* No OFFSET*/
例子2(用非唯一索引键排序时):
Query:
SELECT * FROM message
WHERE thumbs_up <= 98
AND (id < 13 OR thumbs_up < 98)
ORDER BY thumbs_up DESC, id DESC
LIMIT 20
Can be written as:
SELECT m2.* FROM message m1, message m2
WHERE m1.id = m2.id
AND m1.thumbs_up <= 98
AND (m1.id < 13 OR m1.thumbs_up < 98)
ORDER BY m1.thumbs_up DESC, m1.id DESC
LIMIT 20;
例子3:
select * from products as a
join
(select id from products order by id limit M, N) as b
on a.id = b.id;