2016-01-23 1 views
2

У меня есть большая индексированная таблица с более чем 35 миллионами строк. Вот индексы, с именованием, которая показывает их порядок следования столбцов:Почему MySQL выбирает этот индекс и как медленно идет слишком медленно?

IDX_E93438363DAE128B, 
IDX_LIST_ID_EMAIL_ADDRESS_DELETED, 
IDX_LIST_ID_SUBSCRIBED_DELETED_EMAIL_ADDRESS, 
IDX_LIST_ID_SUBSCRIBED_DELETED_FIRST_NAME, 
IDX_LIST_ID_SUBSCRIBED_DELETED_LAST_UPDATED_AT 

Моего запрос этой таблицу на моем среднем, например Amazon RDS занимает свыше 15 минут:

SELECT * FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

спользования EXPLAIN запроса Я вижу, что MySQL предпочитает использовать ключ IDX_LIST_ID_EMAIL_ADDRESS_DELETED, когда я ожидаю, что большинство других клавиш (IDX_LIST_ID_SUBSCRIBED_DELETED_...) будет более оптимальным.

Должен ли я просто доверять двигателю? Является ли 17 минут реалистичным временем, чтобы ждать, когда запрос на столе станет таким большим?

+0

Вам нужно использовать 'SELECT *'? Поступая таким образом, вы заставляете базу данных возвращаться к строке первичного ключа для каждой найденной строки с ее индексом. Кроме того, какой движок? MyISAM или InnoDB? –

+0

Спасибо за ваш ответ. Я уточнил свой запрос только «SELECT id, email_address, first_name, last_name FROM ...», но я все еще получаю ту же проблему. Я использую InnoDB. – Jonathan

+0

Какова производительность при выборе 'select * из индекса использования контакта (idx_list_id_subscribed_deleted_first_name), где ...'? – zedfoxus

ответ

0
SELECT id, email_address, first_name, last_name 
FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

Учитывая приведенный выше запрос, лучший показатель будет

ALTER TABLE `contact` 
CREATE INDEX (`list_id`,`subscribed`,`deleted`,`email_address`,`first_name`,`last_name`) 

Это позволит ему искать все необходимые строки с крайней левой 3-х полей, а все остальные значения находятся справа что. Это предполагает, что id является первичным ключом вашей таблицы, иначе вам придется добавить это значение справа от deleted в этом индексе.

Это должно максимизировать скорость, с которой вы можете запустить этот запрос, по крайней мере, до тех пор, пока просто меняются индексы.

Если с этим индексом, вы все еще возникают проблемы, пожалуйста, дайте нам знать, что результат

SELECT COUNT(*) 
FROM contact 
WHERE list_id = '014c7cba-c124-11e5-b4ea-0a4287b2e8c5' 
AND subscribed = 1 
AND deleted = 0 

возвращается. У вас просто может быть огромное количество строк, на которые может потребоваться время для возврата.