2016-04-28 12 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

私は..

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) 

を提案わずかな列で完全なインデックス付きテーブルを試すこともできます

INDEX my_index_name (ProjectId,RoleId, Tile, id) 

とあなたが(ProjectId, RoleId, Title)(RoleId, ProjectId, Title)インデックスを試すことができ、このよう

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

を使用していますが、インデックス付きの列にnull値がありますか、またはnull値に設定されていますか? – scaisEdge

+0

私は少し答えを更新しました。 – scaisEdge

1

を選択します。彼らはあまり役に立たないかもしれません。問題は、whereに2つの不等式があることです。

これらのうちの1つは、現在の実行計画より優れている可能性があります。しかし、あまり役に立たないかもしれません。

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