Почему следующий запрос копирует данные таблицы?

SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY SourceId, ExternalProductId
HAVING cnt > 1

Есть индекс на (ExternalProductId, SourceId, AnotherField). Объяснение показывает, что индекс используется. Это напечатано в столбце "Extra" объяснения:

Using where; Using index; Using temporary; Using filesort

Когда я запускаю запрос, я вижу через SHOW PROCESSLIST:

Copying to tmp table on disk

Можно ли настроить этот запрос для работы с индексом? Я также не против, если полученные результаты немного неточны из-за других процессов, одновременно работающих с этой таблицей - могу ли я изменить уровень изоляции, чтобы повысить производительность запроса?

2 ответа

Решение

Если вы переверните столбцы в вашем GROUP BY чтобы соответствовать порядку первых двух полей вашего составного индекса, он будет намного эффективнее использовать ваш составной индекс.

SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY ExternalProductId, SourceId
HAVING cnt > 1

Ваш простой запрос должен превратиться в 'Using where; Using index'и избавиться от временной таблицы и файловой сортировки, вызванных другой GROUP BY,

Вы все равно получите те же результаты, но в несколько ином порядке.

Несколько вещей, чтобы попробовать:

  1. MySQL автоматически отсортирует группу по. Если вас не интересует порядок сортировки, добавьте предложение ORDER BY NULL. Это уничтожит сортировку файлов и, возможно, временную таблицу.

  2. Удалите счетчик (*) и используйте имя столбца в индексе вместо подстановочного знака.

Также. Какой у вас индекс? Можете ли вы показать нам полный отчет о создании таблицы?

Другие вопросы по тегам