早上好,
我有一个包含几百万行的表,我需要查看按时间戳排序的数据。
当我试图这样做时
SELECT * FROM table ORDER BY date DESC offset 0 LIMIT 200
MySQL 将对所有数据进行排序,然后将响应 200 行,这是一个性能问题。因为每次我想滚动页面时都订购所有东西是不明智的!
您对我们如何提高性能有任何想法吗?
早上好,
我有一个包含几百万行的表,我需要查看按时间戳排序的数据。
当我试图这样做时
SELECT * FROM table ORDER BY date DESC offset 0 LIMIT 200
MySQL 将对所有数据进行排序,然后将响应 200 行,这是一个性能问题。因为每次我想滚动页面时都订购所有东西是不明智的!
您对我们如何提高性能有任何想法吗?
首先,您需要根据日期字段创建索引。这允许按顺序检索行,而不必在每次发出请求时对整个表进行排序。
其次,对结果集的深入研究越深入,基于索引的分页就越慢。为了显示:
ORDER BY indexedcolumn LIMIT 0, 200
速度非常快,因为它只需要扫描 200 行索引。
ORDER BY indexedcolumn LIMIT 200, 200
比较快,但是需要扫描400行的索引。
ORDER BY indexedcolumn LIMIT 660000, 200
非常慢,因为它需要扫描 660,200 行索引。
注意:即便如此,这可能仍然比没有索引要快得多。
您可以通过几种不同的方式解决此问题。
实现基于值的分页,因此您基于上一页上最后一个结果的值进行分页。例如:
WHERE indexedcolumn>[lastval] ORDER BY indexedcolumn LIMIT 200
将 [lastval] 替换为当前页面的最后一个结果的值。索引允许随机访问特定值,并从该值向前或向后进行。
只允许用户查看前 X 行(例如 1000)。如果他们想要的值是第 2529 个值,那就不好了。
考虑一些分解大表的逻辑方式,例如按第一个字母、年份等,这样用户就不必遇到数百万行的整个结果集,而是需要先深入到特定的子集,这将是一个更小的集合和更快的排序。
如果您将 WHERE 和 ORDER BY 组合在一起,您需要在索引设计中反映这一点,以使 MySQL 能够继续从索引中受益以进行排序。例如,如果您的查询是:
SELECT * FROM mytable WHERE year='2012' ORDER BY date LIMIT 0, 200
然后,您的索引将需要按该顺序位于两列(年份、日期)上。
如果您的查询是:
SELECT * FROM mytable WHERE firstletter='P' ORDER BY date LIMIT 0, 200
然后,您的索引将需要按该顺序位于两列(首字母、日期)上。
这个想法是,只要您将先前的列指定为条件中的常量(单个值),多列上的索引就允许按任何列进行排序。因此,如果您将 A 和 B 指定为 WHERE 条件中的常量,则 A、B、C、D 和 E 上的索引允许按 C 排序。A 和 B 不能是范围。