Оптимизация запроса (выборка из нескольких таблиц с ранжированием)

Osterlitz

Новичок
Привет, помогите оптимизировать запрос на сайте, написанном на php.
В общем сайт представляет собой собрание фотографий, за которые можно голосовать. Вся информация о фотографиях хранится в таблице `photos`:
id(int) | country (int) | city(int)
т.е. каждая фотография сделана в определенной местности. Тип данных - int, т.к. Значение берется из других таблиц (`country` и `city`), названия (`country.name` и `city.name`) соответствуют идентификаторам из таблицы фото. Т.е. чтобы узнать, в каком городе сделан снимок - создает запрос:
Select * from `city` where `city.id`='значение photos.city из таблицы photos'
Аналогично и со странами.
Также есть таблица, в которую заносятся все данные о голосованиях `rate`:
win(int) | value(int) | date(date)
Win - это идентификатор фотографии
Value - значение голосования. Если голосовали "за", то в таблицу попадает значение +2, если против, то -1.
Date - дата голосования.
Таким образом можно составить рейтинг фотографий:
Select *,sum(`value`) as `summa` from `rate` group by `win` where `date` = 'подставляем сюда период за какой надо выбрать значения' order by `summa` desc;
Довольно простой и понятный запрос, а теперь - ВОПРОС!!!
На странице с фотографией необходимо создать 3 графика "местонахождения" в рейтинге фотографии (по городу, по стране и вцелом по сайту).
Другими словами нужно 3 массива, в котором содержалась следующая информация:
$array = ('date20140101' => '1-e место', 'date20140102' => '30-e место, 'date20140103' => '283-е место'... и т.д.);
Это для общего графика. Аналогичные массивы нужны также для города и страны. Т.е. Элемент массива $array['date20140101'] показывает рейтинг фотографии среди всех фотографий, за которые голосовали 1-го января. Соответственно для массивов с городом и страной надо показать на каком месте находилась эта фотография такого-то числа среди фотографий из этого города (страны) за которые голосовали в определенный день. Сложность даже не стом, чтобы подсчитать сумму баллов по необходимым условиям, а сколько узнать рейтинг. Если сначала запросить количество всех возможных результатов по необходимым условиям, создать рейтинг и найти в нем место этой фотграфии - необходимо сделать несколько запросов по таблице `rate` и связать ее с остальными таблицами. А в таблице `rate` Может быть несколько сотен тысяч записей. Что просто "накрывает" сервер. Может можно как-нибудь упростить запрос. Чтобы из него сразу возникал нужный массив. 3 запроса = 3 массива.
Если мои рассуждения неверны, буду рад выслушать критику. Заранее благодарен, очень нужна ваша помощь.
 

hell0w0rd

Продвинутый новичок
По диагонали прочел, мое мнение - когда работаем с рейтингом, который рассчитывается на основании выборки с суммированием, самый простой способ - создать поле, в которое этот рейтинг сохраняется, чтобы в дальнейших запросах его каждый раз не пересчитывать.
 

Osterlitz

Новичок
По диагонали прочел, мое мнение - когда работаем с рейтингом, который рассчитывается на основании выборки с суммированием, самый простой способ - создать поле, в которое этот рейтинг сохраняется, чтобы в дальнейших запросах его каждый раз не пересчитывать.
Согласен, только все равно не выход. Предположим, что на графике выводится информация за год. Соответственно необходимо составить 365 рейтингов. Это многовато. Есть, конечно мысля выводить не 365 значений, а, например, 10. Но необходимо отразить всю картину (с момента публикации фотографии). В этом случае можно также объединить показания. Например, одна точка у фотографии, размещенной год назад будет равна 30-ти дням. В таком случае положение за каждой точки считается как среднее положение за эти 30 дней.

В этом случае алгоритм следующий.
1) мы находим, когда эта фототграфия была загружена (возьмем по умолчанию данные, когда впервые за нее голосовали или против нее). Т.е. из колонки `rate.date` выбираем самую раннюю дату `rate.date` по фотографии `rate.win`/
2) высчитываем сколько дней прошло с этого момента до настоящего дня.
3) делим количество дней на нашу постоянную (например, 10), чтобы составить массив из 10 элементов (10 точек на графике).
4) составляем список периодов за которые надо рассчитать рейтинг. Например, фотография размещена год назад - у нас периоды ('2013-06-01 - 2013-07-01', '2013-07-01 - 2013-08-01', '2013-08-01 - 2013-09-01' .... и т.д.)
5) составляем рейтинг для каждого из этих периодов для каждого из этих периодов, группировкой по `rate.win` и суммированием значений `rate.value`. А также выборкой в зависимости по условию по городу или стране.
6) вот тут самое непонятное - находим положение фотографии в каждом рейтинге.
7) все данные записываем в массив.

Вроде все понятно, но как это реализовать - не пойму. Да и будет ли запрос быстрым. Это надо составить не менее 30-ти рейтингов. С таким количеством действий страница может даже не открыться.
 

AnrDaemon

Продвинутый новичок
Да, составить 365 с четвертью рейтингов. Что вас смущает? Рейтинг у вас пересчитывается раз в сутки, нагрузки, считай, никакой. А на графике вы его тупо отображаете.

P.S.
google:RRDTOOL
 

Osterlitz

Новичок
Да, составить 365 с четвертью рейтингов. Что вас смущает? Рейтинг у вас пересчитывается раз в сутки, нагрузки, считай, никакой. А на графике вы его тупо отображаете.

P.S.
google:RRDTOOL
Это если ежедневно сохранять каждый рейтинг в отдельную ячейку. А как это сделать "на лету". Например, если фотографий несколько тысяч. Если автоматизировать сохранение рейтинга, например, в таблице photos - надо ее 3 ячейки для места в общем рейтинге, по городу и стране. И ежедневно в определенное время проделывать операции по составлению 3-х рейтингов для каждой фотографии. Так что ли? Хорошо, попробую, расскажу о результатах.
 
Сверху