Почему следующий запрос копирует данные таблицы?
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
,
Вы все равно получите те же результаты, но в несколько ином порядке.
Несколько вещей, чтобы попробовать:
MySQL автоматически отсортирует группу по. Если вас не интересует порядок сортировки, добавьте предложение ORDER BY NULL. Это уничтожит сортировку файлов и, возможно, временную таблицу.
Удалите счетчик (*) и используйте имя столбца в индексе вместо подстановочного знака.
Также. Какой у вас индекс? Можете ли вы показать нам полный отчет о создании таблицы?