Новости
Документация
Download
Webboard
Поиск
FAQ/ЧаВо
Обратная связь




MySQL.RU - Webboard



Вернуться
Оптимизация SQL запроса (Андрей) 08/04/2005 - 23:11:29
      Re: Оптимизация SQL запроса! (Роберт) 10/04/2005 - 14:48:22

> Original message text:
> From: Андрей - 08/04/2005 - 23:11:29
> Subject:Оптимизация SQL запроса
> -----------------
>
> есть запрос
> ====================
> SELECT users.id AS uid, games.id AS gid, max(games.end_time) AS time
> FROM users, games
> WHERE (users.id = games.black OR users.id = games.white)
> GROUP BY users.id
> ====================
> задача запроса выбрать такую запись из games для каждого users.id, в которой games.end_time было бы максимальным
>
> Запрос выполняется крайне медленно. И если в WHERE заменить на
> WHERE (users.id = games.black)
> то запрос выполняется в 10 раз быстрее!
> но при этом не хватает данных о games.white и нужно формировать еще один запрос с WHERE (users.id = games.white), а потом из них выбирать максимальный games.end_time
>
> нельзя ли оптимизировать этот запрос так, чтобы все работало быстро? сам пока придумал такое:
> =================
> SELECT uid, gid, max(a.time) as time FROM
> (SELECT users.id AS uid, games.id AS gid, max(games.end_time) AS time
> FROM users, games
> WHERE (users.id = games.black)
> GROUP BY users.id
> UNION
> SELECT users.id AS uid, games.id AS gid, max(games.end_time) AS time
> FROM users, games
> WHERE (users.id = games.white)
> GROUP BY users.id
> ORDER BY uid) AS a GROUP BY uid
> ============
>
> но кажется что это как-то громоздко, хоть и работает в 5-6 раз быстрее первоначального запроса
>


From: Роберт - 10/04/2005 - 14:48:22
Subject:Оптимизация SQL запроса!
-----------------
1) А зачем в твоём новом запросе строчка "ORDER BY uid"? Причём она только во втором унионе...

2)А если вместо
users.id = games.black OR users.id = games.white
написать
users.id in (games.black,games.white)

3) Похоже на то что ты выбираешь последнюю игру в шахматы для каждого игрока. Если ты считаешь что такие запросы к твоей базе данных буду делаться часто - то может тогда стоит просто ввести поле user.LastGID и обновлять его после каждой игры? И тогда дата последней игры (и любая другая последняя информация доступна по простой всязке user.LastGID=game.id
Ведь подумай сам - если база загружается на долю секунды для изменения этой записи - этого никто не заметит. А вот в статистику заходят часто и не хотят там ждать 10 секунд чтобы увидеть когда последний раз и с кем играл их товарищь).

4) Опять же немножко внести изменения в базу данных и ввести новую таблицу , где после каждой игры создавалось бы ешё две записи вносящие:
Insert into Play (PlayerID,GameID)
одна строчка для чёрного , одна для белого! Тогда в последствии тебе не надо будет ПОСТОЯННО мучится с тем что для проверки соответсвия игрока игре тебе надо как сейчас проверять его наличие в списке белых и чёрных игроков.

5) Я немного изменил твой запрос - может так будет быстрее (так как он вначале находит только игроков в каждой базе , а потом за 1 раз связывает их в одну базу)
SELECT uid, gid, max(a.time) as time
FROM
(
SELECT games.black AS uid, max(games.end_time) AS time
FROM games
GROUP BY games.black
UNION
SELECT games.white AS uid, max(games.end_time) AS time
FROM games
GROUP BY games.white
) AS a , user
where users.id=uid
GROUP BY uid


[Это сообщение - спам!]

Последние сообщения из форума

Уважаемые посетители форума MySQL.RU!
Убедительная просьба, прежде чем задавать свой вопрос в этом форуме, обратите внимание на разделы:
- ответы на наиболее часто задаваемые вопросы - FAQ
- раздел документация
- раздел поиск по сообщениям форума и документации
Также, старайтесь наиболее подробно указывать свою ситуацию (версию операционной системы, версию MySQL, версию программного обеспечения, по которому возникает вопрос, текст возникающих ошибок, и др.)
Помните, чем конкретнее Вы опишете ситуацию, тем больше шансов получить реальную помощь.
 Имя:
 E-mail:
 Тема:
 Текст:
Код подтверждения отправки: Code
21375



РЕКЛАМА НА САЙТЕ
  Создание сайтов | |