У меня есть веб-страница, где пользователи загружают & смотреть видео. На прошлой неделе I asked каков наилучший способ отслеживания видеороликов, чтобы я мог отображать наиболее просматриваемые видео на этой неделе (видео из всех дат).Оптимизация GROUP BY & ORDER BY query
Теперь мне нужна помощь в оптимизации запроса, с помощью которого я получаю видео из базы данных. Соответствующие таблицы это:
video (~239371 rows)
VID(int), UID(int), title(varchar), status(enum), type(varchar), is_duplicate(enum), is_adult(enum), channel_id(tinyint)
signup (~115440 rows)
UID(int), username(varchar)
videos_views (~359202 rows after 6 days of collecting data, so this table will grow rapidly)
videos_id(int), views_date(date), num_of_views(int)
В таблице video
держит видео, signup
hodls пользователей и videos_views
содержит данные о просмотрах видео (каждое видео может иметь одну строку в день в этой таблице).
У меня есть этот запрос, который выполняет трюк, но требует ~ 10 секунд для выполнения, и я думаю, что со временем это будет только ухудшаться по мере роста таблицы videos_views
.
SELECT
v.VID,
v.title,
v.vkey,
v.duration,
v.addtime,
v.UID,
v.viewnumber,
v.com_num,
v.rate,
v.THB,
s.username,
SUM(vvt.num_of_views) AS tmp_num
FROM
video v
LEFT JOIN videos_views vvt ON v.VID = vvt.videos_id
LEFT JOIN signup s on v.UID = s.UID
WHERE
v.status = 'Converted'
AND v.type = 'public'
AND v.is_duplicate = '0'
AND v.is_adult = '0'
AND v.channel_id <> 10
AND vvt.views_date >= '2001-05-11'
GROUP BY
vvt.videos_id
ORDER BY
tmp_num DESC
LIMIT
8
Все соответствующие поля индексируются. И вот скриншот результата EXPLAIN: alt text http://img685.imageshack.us/img685/9440/explain.png
Итак, как я могу это оптимизировать?
ОБНОВЛЕНИЕ Это мой запрос, основанный на ответе Quassnoi. Он возвращает правильные видеоролики, но это испортит JOIN в таблице регистрации. Для некоторых записей поле username
равно NULL, для других оно содержит неправильное имя пользователя.
SELECT
v.VID,
v.title,
v.vkey,
v.duration,
v.addtime,
v.UID,
v.viewnumber,
v.com_num,
v.rate,
v.THB,
s.username
FROM
(SELECT
videos_id,
SUM(num_of_views) AS tmp_num
FROM
videos_views
WHERE
views_date >= '2010-05-13'
GROUP BY
videos_id
) q
JOIN video v ON v.VID = q.videos_id
LEFT JOIN signup s ON s.UID = v.VID
WHERE
v.type = 'public'
AND v.channel_id <> 10
AND v.is_adult = '0'
AND is_duplicate = '0'
ORDER BY
tmp_num DESC
LIMIT
8
Вот ResultSet: alt text http://img714.imageshack.us/img714/2954/resultu.png
все будет в порядке. но попытайтесь оценить эти данные в Postgres, проверьте, как это будет стоить – Hao
да, это не может быть и речи! –