2016-04-28 6 views
1

У меня есть таблица с 5 миллионами строк. Я не добавил свои индексы здесь:Индекс 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

Смежные вопросы