Как оптимизировать mysql Distinct? - PullRequest
4 голосов
/ 05 июля 2011

Tbl_responses имеет

  • ID
  • ответ
  • MSGID
  • имя пользователя

Есть 5000 записей. 800 ответов было опубликовано "zac1987". Среди 800 ответов, отправленных "zac1987", 30 различий msgid.

SELECT DISTINCT msgid 
  FROM Tbl_responses 
 WHERE username = 'zac1987';

В настоящее время Explain SQL показывает, что выполнено 800 строк. Как оптимизировать запрос, чтобы было обработано только 30 строк? Я думаю, что должно быть решение, позволяющее избежать зацикливания / фильтрации 800 записей ... точно так же, как замена предложения WHERE предложением JOIN, которое показывается в моем блоге ... ye5.blogspot.com / 2011/07 / optimize -faster-mysql-query-speed.html Я ищу эксперта, который бы нашел решение, позволяющее избежать зацикливания 800 записей.

Мой другой вопрос - почему эта страница http://forge.mysql.com/wiki/Top10SQLPerformanceTips говорит: «Не используйте DISTINCT, когда вы используете или можете использовать GROUP BY», потому что это замедлит запрос? Но я проверил, результат не замедлился, почему?

Ответы [ 4 ]

2 голосов
/ 05 июля 2011

Как вы сказали, попробуйте переписать запрос, используя предложение GROUP BY:

SELECT msgid 
  FROM Tbl_responses 
 WHERE username = 'zac1987' GROUP BY msgid;

И посмотрите на разницу в производительности

1 голос
/ 05 июля 2011

Два запроса эквивалентны:

SELECT DISTINCT msgid 
FROM Tbl_responses 
WHERE username = 'zac1987' ;

и

SELECT msgid 
FROM Tbl_responses 
WHERE username = 'zac1987'
GROUP BY msgid ;

Я предлагаю вам составной индекс на (username, msgid).Это поможет любой версии запроса.

Но было бы лучше, если бы вы создали тестовую таблицу со строками 10 КБ (или даже 100 КБ или 1 МБ) и попробовали планы скорости и выполнения, сначала с простым индексом на(username) и затем с составным индексом на (username, msgid).

Разница будет показана в столбце Extra в плане выполнения, где для первого случая с простым индексом будет отображаться «Используя где, используя временный» , где во втором случае, с составным индексом это покажет «Использование где, используя индекс»

Как указал Тюдор, беспокоиться о скорости с 5000 записями - преждевременная оптимизация.Если у вас есть записи 500 КБ или вы видите снижение производительности, вам следует начать беспокоиться.


Примечание. Эти два запроса эквивалентны НЕ , поэтому вы не всегда можете удалитьПредложение DINSTINT, переместив поле в GROUP BY и ожидая таких же результатов:

SELECT DISTINCT msgid, response
FROM Tbl_responses 
WHERE username = 'zac1987' ;

и

SELECT msgid, response
FROM Tbl_responses 
WHERE username = 'zac1987'
GROUP BY msgid ;
1 голос
/ 05 июля 2011

Проверьте, будет ли индекс покрытия лучше в вашем случае. http://ronaldbradford.com/blog/tag/covering-index/

0 голосов
/ 05 июля 2011

Поместите некоторое условие, например, WHERE username = 'zac1987' AND id = 'XYZ', потому что невозможно отфильтровать строки, используя отличимые и сгруппированные только согласно вашему требованию.

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