Почему следующий запрос копирует данные таблицы? - PullRequest
2 голосов
/ 16 декабря 2010
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 ]

3 голосов
/ 16 декабря 2010

Если вы перевернете столбцы в вашем 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.

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

0 голосов
/ 16 декабря 2010

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...