【问题标题】:MySQL: ORDER BY with RANGE query, bad performanceMySQL:使用 RANGE 查询的 ORDER BY,性能不佳
【发布时间】:2012-08-23 08:58:13
【问题描述】:

我正在处理一个查询,该查询应从包含超过 400,000 条记录MyIsam 表中选择由定义的用户列表发送的最后 20 个帖子。唯一的问题是查询运行时间约为 0.6 秒,有时超过 2 秒。

SELECT post_id
FROM posts
WHERE post_author IN (32, 85, 222, 81, 250,  [..cut..] , 5908, 4930, 6658, 6757, 6398, 6324, 6629)
ORDER BY post_id DESC
LIMIT 20

如果我删除 ORDER BY 查询要快得多,并且它在“post_author”列上使用正确的索引,而不是执行全表扫描...进行查询的最佳方法是什么像这样?


使用 author_index 测试 #1

  • PRIMARY(post_id)
  • author_index (post_author)

时间:0.7s

SELECT post_id
FROM posts
WHERE post_author IN (32, 85, 222, 81, 250,  [..cut..] , 5908, 4930, 6658, 6757, 6398, 6324, 6629)
ORDER BY post_id DESC
LIMIT 20

时间:0.004s

SELECT post_id
FROM posts
WHERE post_author IN (58,68)
ORDER BY post_id DESC
LIMIT 20

使用复合索引测试 #2

  • PRIMARY(post_id)
  • view_posts_index(post_id、post_author)

时间:0.05s

SELECT post_id
FROM posts
WHERE post_author IN (32, 85, 222, 81, 250,  [..cut..] , 5908, 4930, 6658, 6757, 6398, 6324, 6629)
ORDER BY post_id DESC
LIMIT 20

时间:1.5s

SELECT post_id
FROM posts
WHERE post_author IN (58,68)
ORDER BY post_id DESC
LIMIT 20

使用复合索引和 author_index 测试 #3

  • PRIMARY(post_id)
  • view_posts_index(post_id、post_author)
  • author_index (post_author)

时间:0.7s

SELECT post_id
FROM posts
WHERE post_author IN (32, 85, 222, 81, 250,  [..cut..] , 5908, 4930, 6658, 6757, 6398, 6324, 6629)
ORDER BY post_id DESC
LIMIT 20

时间:0.0037s

SELECT post_id
FROM posts
WHERE post_author IN (58,68)
ORDER BY post_id DESC
LIMIT 20

感谢您的帮助。

【问题讨论】:

  • 你有post_author的索引吗?
  • 你的 post_id 列是那个表的索引吗?如果不是,则应将其设置为主键。
  • 尝试创建复合索引(post_author, post_id)
  • 如果表是MyISAM,试试(倒序)复合索引:(post_id, post_author)
  • 看起来没有办法使用具有范围条件和顺序的多重索引......任何解决方案?我已经发布了所有建议的索引和相关查询:(

标签: mysql performance sql-order-by where-in


【解决方案1】:

在 post_author 和 post_id 列上创建索引:

CREATE INDEX ix_post_search ON posts(post_author, post_id);

这将允许 MySQL 仅通过查看该索引来满足整个查询。

【讨论】:

  • 谢谢,现在需要 0.18/0.19 秒。这是一个很好的结果XD,可能它仍然可以改进。
  • 你能发布 EXPLAIN 的结果吗?
【解决方案2】:

我想我会尝试这样做,确保在列作者上有一个索引,并且在唯一 id 上自然也有一个索引:)

SELECT p2.post_id FROM posts p2
WHERE p2.post_id IN (
  SELECT p1.post_id
  FROM posts p1
  WHERE p1.post_author IN (32, 85, 222, 81, 250,  [..cut..] , 5908, 4930, 6658, 6757, 6398, 6324, 6629)
 )
ORDER BY p2.post_id
LIMIT 20

如果它解决了你的问题,请告诉我

【讨论】:

  • 谢谢,我已经尝试过这个解决方案,但是速度变慢了,可能没有限制的子查询包含太多的记录,太多的 id 可供选择。
【解决方案3】:

确保您的查询使用post_id 上的索引(可能在post_author 上,但这不是您的问题的一部分),否则在您的情况下,将在需要时立即启动和停止整个范围扫描生成的行数。

【讨论】:

    猜你喜欢
    • 2022-11-19
    • 1970-01-01
    • 2011-01-09
    • 2019-08-21
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多