我正在寻找一种加速慢(filesort)MySQL查询的方法。
表:
categories (id, lft, rgt)
questions (id, category_id, created_at, votes_up, votes_down)
示例查询:
SELECT * FROM questions q
INNER JOIN categories c ON (c.id = q.category_id)
WHERE c.lft > 1 AND c.rgt < 100
ORDER BY q.created_at DESC, q.votes_up DESC, q.votes_down ASC
LIMIT 4000, 20
如果我移除
ORDER BY
子句,它会很快。我知道 MySQL 不喜欢在同一子句中同时使用 DESC
和 ASC
排序,因此我尝试为 questions
表添加组合索引 (created_at, votes_up)
并从 ORDER BY
子句中删除 q.votes_down ASC
。这并没有起到帮助作用,因为 WHERE
子句会阻碍,它通过来自另一个 (categories
) 表的列进行筛选。即使它可以工作,也不完全正确,因为我确实需要 q.votes_down ASC
条件。在这种情况下,如何提高性能的好策略是什么?如果可能的话,我想避免重构表结构。
编辑:
CREATE TABLE `categories` (
`id` int(11) NOT NULL auto_increment,
`lft` int(11) NOT NULL,
`rgt` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `lft_idx` (`lft`),
KEY `rgt_idx` (`rgt`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `questions` (
`id` int(11) NOT NULL auto_increment,
`category_id` int(11) NOT NULL,
`votes_up` int(11) NOT NULL default '0',
`votes_down` int(11) NOT NULL default '0',
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `questions_FI_1` (`category_id`),
KEY `votes_up_idx` (`votes_up`),
KEY `votes_down_idx` (`votes_down`),
KEY `created_at_idx` (`created_at`),
CONSTRAINT `questions_FK_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE q ALL questions_FI_1 NULL NULL NULL 31774 Using filesort
1 SIMPLE c eq_ref PRIMARY,lft_idx,rgt_idx PRIMARY 4 ttt.q.category_id 1 Using where
SHOW CREATE TABLE
иҫ“еҮәжҲ–EXPLAIN
зҡ„иҫ“еҮәгҖӮдҪ иҝҳжңүLIMIT 4000, 20
гҖӮеҰӮжһңдҪ йңҖиҰҒеё®еҠ©еҲҶжһҗжҹҘиҜўпјҢиҜ·еҸ‘еёғжүҖжҸҗеҲ°зҡ„жҹҘиҜўзҡ„иҫ“еҮәгҖӮ - N.B.LIMIT OFFSET
子句背后的情况。 - N.B.