目前该表具有以下索引:
查询:
SELECT `topics.*`
FROM `topics`
WHERE (table.forum_id = ? OR table.other_forum_id = ?)
ORDER by sticky, replied_at DESC LIMIT 25
我尝试在以下内容中添加索引:
这是一个论坛,试图在论坛中获得前25个主题,但在顶部放置sticky
主题(粘性是粘性/非粘性的二进制字段)。
我已经阅读了很多关于优化ORDER BY
的所有内容,但没有运气。这是MySQL 5.1, INNODB
。任何帮助将不胜感激。
EDITS
根据评论中的要求(对不起,如果我做错了 - 在SU上发布新内容)。 EXPLAIN的结果:
id = 1
select_type = SIMPLE
table = topics
type = index_merge
possible_keys = index_topics_on_forum_id,index_topics_on_sticky_and_replied_at,index_topics_on_forum_id_and_replied_at,index_topics_on_video_forum_id,index_forum_id_on_video_forum_id,
keys = index_topics_on_forum_id,index_topics_on_video_forum_id
key_len = 5,5
ref = NULL
rows = 13584
Extra =使用union(index_topics_on_forum_id,index_topics_on_video_forum_id);用在哪里;使用filesort
SHOW INDEXES FROM主题返回https://gist.github.com/1079454 - 无法在此处显示格式。
编辑2
SELECT `topics`.*
FROM `topics`
WHERE topics.forum_id=4
ORDER BY sticky desc, replied_at DESC
跑得非常快(1.4毫秒)。当我将topics.forum_id更改为topics.video_forum_id时,查询也是如此 - 只是当我在查询中使用or时,查询时才会这样。
答案 0 :(得分:1)
我认为这应该非常快。
索引:
ALTER TABLE `topics`
ADD INDEX `forum` (`forum_id` ASC, `sticky` ASC, `replied_at` DESC),
ADD INDEX `other_forum` (`other_forum_id` ASC, `sticky` ASC, `replied_at` DESC);
查询:
(
SELECT `topics.*`
FROM `topics` USE INDEX (`forum`)
WHERE `topics`.forum_id = ?
ORDER by sticky, replied_at DESC
LIMIT 25
) UNION (
SELECT `topics.*`
FROM `topics` USE INDEX (`other_forum`)
WHERE `topics`.other_forum_id = ?
ORDER by sticky, replied_at DESC
LIMIT 25
)
ORDER by sticky, replied_at DESC
LIMIT 25
答案 1 :(得分:0)
尝试索引[forum_id,sticky,replied_at desc]和[other_forum_id,sticky,replied_at desc]
您可以尝试将查询写为联合:
SELECT `topics.*` FROM `topics` WHERE (table.forum_id = ?)
UNION
SELECT `topics.*` FROM `topics` WHERE (table.other_forum_id = ?)
ORDER by sticky, replied_at DESC LIMIT 25
答案 2 :(得分:0)
使用MySQL的EXPLAIN命令了解与查询相关的费用:
EXPLAIN SELECT ...
注意表扫描,这可能是昂贵的。
此外,MySQL可能会也可能不会使用索引。这完全取决于查询优化器如何理解您的查询。
FORCE INDEX
可能会有所帮助,因为这个选项告诉MySQL,表扫描将是超级昂贵的。看看here。
答案 3 :(得分:0)
您可以尝试两件事:
一个,索引在:
(forum_id, sticky, replied_at)
(other_forum_id, sticky, replied_at)
使用您的原始查询或Karolis的建议或
二,索引在:
(forum_id)
(other_forum_id)
(sticky, replied_at)