2016-04-28 60 views
1

我有一個500萬行的表。我這裏沒加我的指標:MySQL索引與訂購

CREATE TABLE `my_table` (
    `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `Title` CHAR(200) NULL DEFAULT NULL, 
    `ProjectId` INT(10) UNSIGNED NOT NULL, 
    `RoleId` INT(10) UNSIGNED NOT NULL, 
    PRIMARY KEY (`Id`) 

) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB; 

當我運行下面的SQL,它需要超過1分鐘。

SELECT * 
FROM `my_table` t 
WHERE 
    t.ProjectId IN (123, 456, 789) AND 
    t.RoleId IN (111, 222, 333) 
ORDER BY Title DESC 
LIMIT 25 

問題是,如何正確地爲表添加索引。你能提供任何解決方案嗎?

Explain for index "ProjectId" and "RoleId" is: 
key = IndxProjectIdRoleId 
ref = NULL, 
rows: 32,463 
Extra: Using where; Using filesort 

感謝您的任何建議。

回答

0

我提出一個綜合指數

INDEX my_index_name (ProjectId,RoleId) 
你的情況

..

CREATE TABLE `my_table` (
    `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `Title` CHAR(200) NULL DEFAULT NULL, 
    `ProjectId` INT(10) UNSIGNED NOT NULL, 
    `RoleId` INT(10) UNSIGNED NOT NULL, 
    PRIMARY KEY (`Id`), 
    INDEX my_index_name (ProjectId,RoleId) 
) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB; 

最終檢查是否具有更多的選擇性反向

INDEX my_index_name (RoleId, ProjectId) 

,做你的表有事實只有幾列你也可以嘗試一個完整的索引表

INDEX my_index_name (ProjectId,RoleId, Tile, id) 

,並選擇這種方式

SELECT Id, Title, ProjectId, RoleId 
FROM `my_table` t 
WHERE 
    t.ProjectId IN (123, 456, 789) AND 
    t.RoleId IN (111, 222, 333) 
ORDER BY Title DESC 
LIMIT 25; 
+0

是的,我用一個名爲「IndxProjectIdRoleId」的複合索引 – sanj

+0

你在索引列中有空值還是總是設置爲非空值? – scaisEdge

+0

我已經稍微更新了答案。 – scaisEdge

1

可以嘗試(ProjectId, RoleId, Title)(RoleId, ProjectId, Title)指標。他們可能沒有多大幫助。問題是你在where有兩個不等式。

其中之一可能會比當前的執行計劃更好。但是,這可能沒有多大幫助。

對於多列索引,MySQL實際上擁有很好的documentation。您可能想要查看它。

查詢的更復雜的版本可能會更好地工作:

(SELECT * 
FROM `my_table` t 
WHERE t.ProjectId = 123 AND t.RoleId = 111 
ORDER BY Title DESC 
LIMIT 25 
) UNION ALL 
(SELECT * 
FROM `my_table` t 
WHERE t.ProjectId = 123 AND t.RoleId = 456 
ORDER BY Title DESC 
LIMIT 25 
) 
UNION ALL 
. . . -- The other 7 combinations 
ORDER BY Title DESC 
LIMIT 25; 

這更長的時間查詢的版本可以採取的任何上述指標的優勢,所以每個人都應該是相當快的。最後,查詢必須排序高達9 * 25(225)條記錄,即使沒有索引,該記錄也應該很快。

+0

我試圖檢查 – sanj