powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизировать запрос в больших таблицах
19 сообщений из 19, страница 1 из 1
Оптимизировать запрос в больших таблицах
    #38885843
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица users (300к записей), там данные о игроках, есть таблица games (2кк записей), это сыгранные игры игроками. Задача: вывести топ 10 игроков по убийствам за последнюю неделю.
Т.е. мы берем таблицу games, в ней есть id игрока и kills сколько он убил за конкретную игру, для каждого id суммируем его убийства в каждой игре (которая прошла не позже чем неделю назад (время сыгранной игры в поле date)), делаем сортировкой по убийствам топ 10, и по полученным id этих игроков, из таблицы users достаем поля fname, lname, photo_50. Это мое представление того, как все делается, и написал такой запрос (только нет условия на то, что игра должна быть сыграна не позже чем неделю назад, не знал уже куда втулить):
Код: sql
1.
2.
3.
4.
5.
6.
SELECT users.fname, games.id, SUM(games.kills) as playerKills
FROM games,users
WHERE games.id=users.id
GROUP BY games.id
ORDER BY playerKills DESC
LIMIT 0,10


Проблема в том, что запрос выполняется 15 секунд. Такой запрос:
Код: sql
1.
SELECT id, SUM(kills) as playerKills FROM games GROUP BY id ORDER BY playerKills DESC LIMIT 0,10


выполняется 3.5 сек., а такой:
Код: sql
1.
SELECT id, SUM(kills) as playerKills FROM games GROUP BY id


выполняется 0.0007 сек.
Индексы:
таблица users - primary индекс по полю id
таблица games - индекс по полю id, и индекс по двум полям kills,date.
Всем кто отзовется огромное спасибо, уже кучу времени убил на этот запрос, никак не поддается.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38885948
jucus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Насколько мне известно, сортировка по SUM на больших данных - это проблема, которую одним запросом не обойти.

Рискну предложить вариант с временной таблицей.

Что-то вроде:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
DROP TABLE IF EXISTS ksum;

CREATE TEMPORARY TABLE ksum (PRIMARY KEY id(user_id), INDEX kills(kills) ) AS
(
SELECT user_id, sum(kills) as kills
FROM games
WHERE date > DATE_SUB(CURDATE(),INTERVAL 7 DAY)
GROUP BY user_id
);

SELECT users.fname, ksum.user_id, ksum.kills
FROM ksum, users
WHERE ksum.user_id = users.id
ORDER BY ksum.kills DESC 
LIMIT 0,10;



Условие для даты зависит от изначального формата поля.
Запросы выше созданы для таких таблиц:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
--
-- Структура таблицы `games`
--

CREATE TABLE IF NOT EXISTS `games` (
  `user_id` int(11) DEFAULT NULL,
  `kills` int(11) DEFAULT NULL,
  `date` date DEFAULT NULL,
  KEY `kills_date` (`kills`,`date`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB;

--
-- Структура таблицы `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fname` varchar(50) DEFAULT NULL,
  `lname` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38885983
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizel,

планы смотри.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886020
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizel,

вывести топ 10 игроков по убийствам за последнюю неделю.


ну и где у тебя "за последнюю неделю" ?
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886023
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ScareCrowTurboDizel,

планы смотри.

какие планы, если запрос в принципе не оптимизируется?
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886025
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GROUP BY games.id


group by у тебя неправильный.

WHERE games.id=users.id

where возможно тоже.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886065
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
jucusНасколько мне известно, сортировка по SUM на больших данных - это проблема, которую одним запросом не обойти.

Рискну предложить вариант с временной таблицей.
А если этот запрос будет выполнятся по 10-20 раз в секунду? Игроки как бы будут заходить, смотреть на ТОП и все такое. Это не будет слишком тяжко для базы данных?). И ещё, запрос к бд идет из php, может в таком случае некоторую часть лучше переместить для обработки уже в php скрипте? Если нет, то попробую с временной таблицей сделать.

MasterZivну и где у тебя "за последнюю неделю" ?
Я же написал.
TurboDizel(только нет условия на то, что игра должна быть сыграна не позже чем неделю назад, не знал уже куда втулить)
Не хотелось бы грубить, конечно, учитывая, что я хочу получить помощь, но как Вы даете мне советы, если вопрос мой полностью не прочитали? Учитывая, что написали 3 сообщения и ни одного совета.

MasterZivGROUP BY games.id
group by у тебя неправильный.

WHERE games.id=users.id
where возможно тоже.
Я понимаю, что мой запрос в общем не правильный (как минимум потому, что он выполняется 15 секунд), поэтому и обратился за помощью, в надежде услышать советы, как, например, от jucus .
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886068
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Или наверное было бы плавильным делать такой запрос раз в час например, и класть данные в отдельную таблицу, и брать данные уже из этой таблицы. Т.е. обновлять ТОП раз в час. тогда запросы будут не такими объемными. Или Вы это и имели в виду?)
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886084
jucus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TurboDizelИли наверное было бы плавильным делать такой запрос раз в час например, и класть данные в отдельную таблицу, и брать данные уже из этой таблицы. Т.е. обновлять ТОП раз в час. тогда запросы будут не такими объемными. Или Вы это и имели в виду?)
Если есть необходимость выдавать этот результат часто, то определенно, я кешировал бы результат (да хоть в файл). Стратегия и средства кэширования это уже другая история - все зависит от условий задачи и имеющихся средств.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886398
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot TurboDizel][q
Я понимаю, что мой запрос в общем не правильный (как минимум потому, что он выполняется 15 секунд), поэтому и обратился за помощью, в надежде услышать советы, как, например, от jucus .[/quot


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

как ты думаешь, что проще и быстрее, просчитать сумму по 2 мнл записей, или по 5 тысячи за последнюю неделю?
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886399
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizelИли наверное было бы плавильным делать такой запрос раз в час например, и класть данные в отдельную таблицу, и брать данные уже из этой таблицы. Т.е. обновлять ТОП раз в час. тогда запросы будут не такими объемными. Или Вы это и имели в виду?)
ты запрос то сначала напиши, а потом уже думать будешь, когда его пускать.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886726
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivкак ты думаешь, что проще и быстрее, просчитать сумму по 2 мнл записей, или по 5 тысячи за последнюю неделю?
А, блин, логично. Попробовал вот так.
Код: sql
1.
SELECT id, SUM(kills) as playerKills FROM games WHERE date > curdate()-interval 7 day GROUP BY id ORDER BY playerKills DESC LIMIT 0,10


Уже 0.72 сек. Данные из таблицы users не нужны, теперь мне нужно просто получить те данные, которые я уже вот получаю этим запросом, только быстрее.
Вообще, если не ограничивать на 10 человек, то в итоге получается 90к записей, и я так понимаю вся тягота запроса в том, что он сортирует по не проиндексированному полю сумм kills среди 90к записей. Как мне в этом моменте ускорить запрос можно?
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886740
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizelВообще, если не ограничивать на 10 человек, то в итоге получается 90к записей, и я так понимаю вся тягота запроса в том, что он сортирует по не проиндексированному полю сумм kills среди 90к записей. Как мне в этом моменте ускорить запрос можно?Никак. Только предагрегация.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886940
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizelВообще, если не ограничивать на 10 человек, то в итоге получается 90к записей, и я так понимаю вся тягота запроса в том, что он сортирует по не проиндексированному полю сумм kills среди 90к записей. Как мне в этом моменте ускорить запрос можно?

хуже того, этот запрос сортирует по вычисляемому полю .

больше его уже никак не ускорить, при условии что есть индекс по дате игры, он используется, и условие join game and user у тебя правильное.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886942
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizel,

мне кажется, что 0.7 для такого запроса вполне приемлемо. часто он вызывался не должен.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38886958
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вариант не расмотрели
Код: sql
1.
2.
3.
4.
5.
6.
7.
select * 

from

(select iduser,sum(kills) as 'total' from games where ts < 'xxxx xx xx xxxxxx' group by iduser,order by `total` desc limit 10) t 

join users u on (u.id = t.iduser)
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38887206
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Правильно ли будет делать такой запрос раз в минуту? Запишу эти данные в отдельную таблицу, а игроки пусть из неё уже тянут топ. А то по всей видимости же пока БД этот мой запрос будет 0.7 сек делать, то все остальные запросы от игроков будут ждать.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38887655
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TurboDizelПравильно ли будет делать такой запрос раз в минуту? Запишу эти данные в отдельную таблицу, а игроки пусть из неё уже тянут топ.

Ещё раз. Если этот запрос и так редко пользователем вызывается, то нет смысла его "кэшировать".
Но решать тебе -- кроме тебя твою задачу никто не знает.

TurboDizelА то по всей видимости же пока БД этот мой запрос будет 0.7 сек делать, то все остальные запросы от игроков будут ждать.

Не будут.
...
Рейтинг: 0 / 0
Оптимизировать запрос в больших таблицах
    #38889001
TurboDizel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivЕщё раз. Если этот запрос и так редко пользователем вызывается, то нет смысла его "кэшировать".
TurboDizelА если этот запрос будет выполнятся по 10-20 раз в секунду? Игроки как бы будут заходить, смотреть на ТОП и все такое.
Ну ладно, кроном сделаю вызов раз в минуту или лучше раз в 5 минут, так как будет ещё один ТОП с похожей выборкой. Спасибо за ответы!
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Оптимизировать запрос в больших таблицах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]