2014-01-19 88 views
1

請幫我選索引表,以避免發生運行特定的查詢filesorting。優化索引來避免使用filesorting

所以,有兩個表demo_userdemo_question

CREATE TABLE `demo_user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(50) NOT NULL, 
    `age` INT(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `age` (`age`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

CREATE TABLE `demo_question` (
    `id` INT(11) NOT NULL AUTO_INCREMENT, 
    `userId` INT(11) NOT NULL, 
    `createdAt` DATETIME NOT NULL, 
    `question` VARCHAR(50) NOT NULL, 
    PRIMARY KEY (`id`), 
    INDEX `userId` (`userId`), 
    INDEX `createdAt` (`createdAt`), 
    CONSTRAINT `FK_demo_question_demo_user` FOREIGN KEY (`userId`) REFERENCES  `demo_user` (`id`) 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

一些樣本數據:

INSERT INTO `demo_user` VALUES ('u1', 20); 
INSERT INTO `demo_user` VALUES ('u2', 25); 
INSERT INTO `demo_user` VALUES ('u3', 27); 
INSERT INTO `demo_user` VALUES ('u4', 33); 
INSERT INTO `demo_user` VALUES ('u5', 19); 
INSERT INTO `demo_question` VALUES (2, '2014-01-19 15:17:13', 'q1'); 
INSERT INTO `demo_question` VALUES (3, '2014-01-19 15:17:43', 'q2'); 
INSERT INTO `demo_question` VALUES (5, '2014-01-19 15:17:57', 'q3'); 

在這些表中,我試圖運行下面的查詢:

select * 
from demo_question q 
left join demo_user u on q.userId = u.id 
where u.age >= 20 and u.age <= 30 
order by q.createdAt desc 

嘗試按0123排序結果時,此查詢的說明檢測到filesort列

+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra       | 
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 
| 1 | SIMPLE  | q  | ALL | userId  | NULL | NULL | NULL | 3 | Using temporary; Using filesort | 
| 1 | SIMPLE  | u  | ALL | PRIMARY,age | NULL | NULL | NULL | 5 | Using where; Using join buffer | 
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+ 

所以我的問題:什麼可以做,以防止filesorting在運行這樣的查詢,因爲它會降低性能時,有兩個表格中較大的行數?

+0

嘗試將其與內部聯接,而不是一個左連接,以防MySQL的是太愚蠢地看到,它這樣做,反正。 –

+0

@Denis不幸的是內部聯接不會改變任何東西 – gatisl

+0

嘗試把兩列到inndex,而不是2個指標上demo_question即INDEX'userId'('userId')成爲INDEX'userId'('userId','createdAt') –

回答

1

您已擁有該查詢可能使用的所有索引。有兩個問題。首先,這絕對不是一個左連接,它是一個內連接,你需要理解爲什麼這是真的,它應該以這種方式寫,即使優化器可能意識到你的意圖(儘管表達方式不同)這可以解釋爲什麼改變查詢不會改變查詢計劃。

的第二個問題是,你不能指望優化選擇與一個小數據集,這將是一樣會在更大的數據集可以使用的計劃。

優化器對「成本」做出決定,並且在一小部分數據上使用索引的成本被假定爲相對較高......因此它現在會放棄該動作,但不可能在以後...隨着數據集的變化,您在這裏獲得的計劃將會發生變化。

+0

很好的解釋。謝謝你的時間。 – gatisl