繁体   English   中英

从一个巨大的 MySQL 表中以相反的顺序选择 N 行

[英]Select N rows in the reverse order from a huge MySQL table

我需要从一个巨大的 MySQL 表中以相反的顺序选择 N 行。

CREATE TABLE fitness (
  user int unsigned DEFAULT '0',
  health int unsigned DEFAULT '0',
  ts int unsigned DEFAULT '0'
) ENGINE=InnoDB CHARSET=utf8

表中有索引,这里不显示。 该表总共包含数百万个条目,每个user包含数十万个条目。

我需要按ts排序的相反顺序获取行,如下所示。

mysql> select * from fitness where user=1 and ts < 1234567 order by ts desc limit 100;

这有效。 然而,这个查询非常慢,因为它需要获取所有匹配的记录,排序并给出前 100 个结果。 user=1 and ts < 1234567可能有几十万匹配记录,因此上面的查询很慢。

任何建议如何做得更好?

根据您的问题标题,您运行的查询结果是可以的,但是您询问需要另一个问题的更快的查询.. 你应该做的第一件事是使用EXPLAIN来了解速度的时间。

你应该做的第二件事是索引FORCE INDEX Mysql doc。

FORCE INDEX 提示的作用类似于 USE INDEX (index_list),此外还假定表扫描非常昂贵。 换句话说,仅当无法使用命名索引之一来查找表中的行时才使用表扫描。

因此,使用强制索引更改您的选择查询。

mysql> select * 
from fitness 
FORCE INDEX (index_name)
where user=1 and ts < 1234567 order by ts desc limit 100;

这是Henrik Peinar 的一篇好文章

为 user 和 ts 创建索引。 即使这些是 int,索引也会改进查询。

根据其他答案,在userts上创建索引。 考虑创建一个完整的覆盖索引,这样它就不需要返回到原始表,例如, create index IX_test on fitness (user, ts, health).

您可能会获得更好的性能,使 ts 下降......但这应该无关紧要,例如, create index IX_test on fitness (user, ts desc, health).

首先确保您的索引在user上,然后是ts 这意味着它可以直接寻找用户和适当的位置(数据已经适当排序,因此不需要新排序)。 如果首先是ts然后是user ,则需要进行大量过滤才能将数据取出。

更新:我确实在这里放了一个例子来演示,但在 SQL Server 上。 它表明该索引工作得很好 - 但它可能会混淆人们/让人们走上红鲱鱼的道路,所以我删除了它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM