mysql - 有效地选择前 n 行

标签 mysql

所以我有一个表,可能有数百万行,

user   | points
---------------
user1  | 10
user2  | 12
user3  | 7
...

并且想要SELECT * FROM mytable ORDER BY points LIMIT 100, 1000 现在工作正常,但速度非常慢(在大表上),因为它拒绝使用任何类型的索引,而是执行全表扫描。我怎样才能使它更有效率?

我的第一个(明显的)想法是在 points DESC 上使用索引,但后来我发现 MySQL 根本不支持这些。

接下来,我尝试反转 points 的符号,这意味着基本上在 -points 上有一个升序索引,这也没有帮助,因为它不使用索引进行排序

最后,我尝试使用 force index,这几乎没有产生任何性能改进,因为它仍然获取整个表,但不排序(在 EXPLAIN 中使用 filesort: false )

我确信这一定是一个已解决的问题,但我没有在网上找到任何有用的信息。任何提示将不胜感激。

最佳答案

从查询中获得更好性能的一些方法。

从不从不使用SELECT *。这是菜鸟的错误。它基本上告诉查询规划器它需要给你一切。 始终 在结果集中枚举您想要的列。这就是您想要的查询(假设您没有过度简化您的问题)。

 SELECT user, points
   FROM table
  ORDER BY points
  LIMIT 100,1000

使用复合索引。对于您的查询,(points, user) 上的复合索引将允许使用部分索引扫描来满足您的查询。这应该比全表排序更快。 MySQL 可以向后或向前扫描索引,因此您无需担心降序

要添加正确的索引,请使用这样的命令。

ALTER TABLE table ADD INDEX points_user (points, user);

编辑。反对在此处使用 SELECT * 的建议是基于 (1) 我未经证实的怀疑,即所讨论的表过于简单并且在现实生活中有其他列,以及 (2) 索引有时具有的不便现实精确匹配查询以获得最佳性能结果。

根据经验,我坚持我的观点,即在对性能敏感的查询中使用 SELECT * 不是好的工程实践(除非您非常喜欢该查询以至于想再次使用它又一次)。

关于mysql - 有效地选择前 n 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41818357/

相关文章:

mysql - 如何从 mysql 查询中获取关注者/关注列表

java - 我在 java 和 mysql 连接中遇到错误..它与 java 和 mysql 中的日期比较有关

MySQL - 提高慢速子查询的性能

PHP ."INSERT INTO"通过 PHP mysqli_query 运行两次!

php - HTML5 日期时间本地显示 01-01-1970 01 :00 When its empty

mysql - 用户 'abc1234' @'WIN-TQV06J8SPLP' 的访问被拒绝(使用密码 : YES)]

java - 如何允许桌面应用程序访问 Microsoft 服务器上的 MySQL 数据库?

php - 这里有没有人试过 PEAR

php - PHP 中 MySQL 查询的当前和前一天

mysql - 这个MySQL命令有什么问题?