Ух ты, мужик, тебе действительно нравится использовать круглые скобки. : -)
Вы правы, составной индекс может помочь. Вы могли бы даже сделать это индексом покрытия. Возможно, я либо попробую использовать индекс Grid_Points(Map_Id,X,Y)
, либо индекс Grid_Points(Points,Update_Stamp,User_No)
.
Всегда проверяйте оптимизацию запросов с помощью EXPLAIN
, чтобы узнать, использует ли оптимизатор ваш индекс. Прочтите этот раздел документации, пока не поймете загадочные примечания в отчете EXPLAIN.
Отчет EXPLAIN, вероятно, покажет вам, какой индекс он решит использовать. Вы должны знать, что MySQL использует только один индекс на таблицу в данном запросе.
Вот как я бы написал этот запрос, полагаясь на порядок приоритетов между AND
и OR
вместо множества вложенных скобок:
SELECT GP.Map_Id, GP.User_No, GP.X, GP.Y, GP.Points, GP.Update_Stamp
FROM Grid_Points GP LEFT JOIN Grid_Points GP2
ON GP2.Map_Id = GP.Map_Id AND GP2.X = GP.X AND GP2.Y = GP.Y
AND (
GP2.Points > GP.Points
OR
GP2.Points = GP.Points
AND GP2.Update_Stamp > GP.Update_Stamp
OR
GP2.Points = GP.Points
AND GP2.Update_Stamp = GP.Update_Stamp
AND GP2.User_No < GP.User_No
)
WHERE GP2.User_No IS NULL;
Вы используете мой любимый метод для нахождения наибольшего числа групп в MySQL. MySQL не очень хорошо оптимизирует GROUP BY
(часто используется временная таблица, которая сериализуется на диск), поэтому используемое левое решение для внешнего соединения обычно намного лучше, по крайней мере для MySQL. В других брендах СУБД это решение может не иметь такого преимущества.