我試圖找到一種方法來加快緩慢(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
命令,所以我嘗試將(created_at, votes_up)
複合索引添加到questions
表中,並從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
您是否對所有列進行了索引? – BenOfTheNorth 2012-02-26 12:04:37
您沒有爲2個表格發佈'SHOW CREATE TABLE'的輸出,也沒有發佈'EXPLAIN'的輸出。你也有'LIMIT 4000,20'。如果您需要幫助分析查詢,請發佈上述查詢的輸出。 – 2012-02-26 12:06:48
@Ben Griffiths:所有列都有索引。 – Ree 2012-02-26 12:07:31