Как оптимизировать этот запрос MySQL - PullRequest
5 голосов
/ 27 мая 2010

Этот запрос работал нормально, когда база данных была маленькой, но теперь, когда в базе данных есть миллионы строк, я понимаю, что мне следовало подумать об оптимизации этого раньше. Он просматривает более 600 000 строк и использует где; Используя временные; Использование сортировки файлов (что приводит к времени выполнения 5-10 секунд). Он использует индекс в поле 'тип_толк.'

SELECT username, SUM( outcome ) AS wins, COUNT( * ) - SUM( outcome ) AS losses
FROM tblBattleHistory
WHERE battle_type =  '0' && outcome <  '2'
GROUP BY username
ORDER BY wins DESC , losses ASC , username ASC 
LIMIT 0 , 50

Ответы [ 3 ]

5 голосов
/ 27 мая 2010

Похоже, вам нужен индекс для username, battle_type, outcome или username, outcome, battle_type.

3 голосов
/ 27 мая 2010

Посмотрим, что вы делаете:

  1. Найти строки с типом боя = 0 и результатом <2 </li>
  2. Заказ по имени пользователя для группировки
  3. Вычисление агрегации и сворачивание строк для разных имен пользователей
  4. Заказ по динамически рассчитанным полям

На шаги 3 и 4 вы не имеете никакого влияния. Шаг 2 в его текущей форме не может извлечь выгоду из каких-либо индексов, поскольку outcome < 2 является условием диапазона, хотя индекс для (тип_боя, исход, имя пользователя) выглядит очень заманчиво.

Предполагая, что outcome является перечислением 0,1,2,3..., вы можете изменить условие диапазона на сравнение на равенство и использовать индекс по (тип_боя, исход, имя пользователя):

SELECT username, SUM( outcome ) AS wins, COUNT( * ) - SUM( outcome ) AS losses
FROM tblBattleHistory
WHERE battle_type = 0 AND outcome IN (0, 1)
GROUP BY username
ORDER BY wins DESC , losses ASC , username ASC 
LIMIT 0 , 50

Если outcome не является перечислением, подойдет индекс on (тип_боя, исход). Индекс только для (battle_type) теперь является избыточным, поскольку battle_type является префиксом в составном индексе.

3 голосов
/ 27 мая 2010

Прежде всего, убедитесь, что у вас хорошие индексы (как уже упоминали другие).

Однако похоже, что вы создаете какую-то таблицу лидеров для веб-страницы. Мой первый вопрос: действительно ли вам нужно выполнить этот запрос в реальном времени? Не могли бы вы создать в своей базе данных таблицу (или добавить столбец выигрышей и проигрышей в таблицу пользователей) с результатами этого запроса и просто периодически обновлять ее?

...