Я создаю сайт рекомендаций для видео (думаю, пандора для музыкальных видео) в python и MySQL. У меня три таблицы в моем бб:Как ускорить (или разбить) этот запрос MySQL?
video - таблица с видео. Данные не меняются. Колонки:
CREATE TABLE `video` (
id int(11) NOT NULL AUTO_INCREMENT,
website_id smallint(3) unsigned DEFAULT '0',
rating_global varchar(128) DEFAULT '0',
title varchar(256) DEFAULT NULL,
thumb_url text,
PRIMARY KEY (`id`),
KEY `websites` (`website_id`),
KEY `id` (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=49362 DEFAULT CHARSET=utf8
video_tag - таблица тегов (атрибутов), связанные с каждым видео. Не меняется.
CREATE TABLE `video_tag` (
id int(7) NOT NULL AUTO_INCREMENT,
video_id mediumint(7) unsigned DEFAULT '0',
tag_id mediumint(7) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `video_id` (`video_id`),
KEY `tag_id` (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=562456 DEFAULT CHARSET=utf8
user_rating - таблица хороших или плохих оценок, которые пользователь дал каждый тег. Данные всегда меняются.
CREATE TABLE `user_rating` (
id int(11) NOT NULL AUTO_INCREMENT,
user_id smallint(3) unsigned DEFAULT '0',
tag_id int(5) unsigned DEFAULT '0',
tag_rating float(10,5) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `video` (`tag_id`),
KEY `user_id` (`user_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=447 DEFAULT CHARSET=utf8
Основываясь на предпочтениях пользователя, я хочу, чтобы выиграть каждое непросмотренное видео, и попытаться предсказать, что они будут, как лучше. Это привело к следующему массивным запроса, который занимает около 2 секунд, чтобы завершить за 50000 видео:
SELECT video_tag.video_id,
(sum(user_rating.tag_rating) * video.rating_global) as score
FROM video_tag
JOIN user_rating ON user_rating.tag_id = video_tag.tag_id
JOIN video ON video.id = video_tag.video_id
WHERE user_rating.user_id = 1 AND video.website_id = 2
AND rating_global > 0 AND video_id NOT IN (1,2,3) GROUP BY video_id
ORDER BY score DESC LIMIT 20
Я отчаянно нужно, чтобы сделать это более эффективным, так что я просто нужен совет относительно того, что наилучшим направлением является. Некоторые идеи я рассмотрел:
а) Ремонтное моя дб структура таблицы (не знаю, как)
б) Разгрузка более группирования и агрегирования в Python (не придумал, как присоединиться три таблицы что на самом деле быстрее)
с) Хранить не меняющиеся таблицы в памяти, чтобы попытаться и время скорости вычислений (ранее мастерить не принесли никаких успехов еще ..)
Как бы вы рекомендовали сделать это более эффективное ?
Спасибо!
-
По желанию в комментариях, EXPLAIN SELECT .. показывает:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE user_rating ref video,user_id user_id 3 const 88 Using where; Using temporary; Using filesort
1 SIMPLE video_tag ref video_id,tag_id tag_id 4 db.user_rating.tag_id 92 Using where
1 SIMPLE video eq_ref PRIMARY,websites,id PRIMARY 4 db.video_tag.video_id 1 Using where
Вы даже не прикладываете свою структуру таблицы, как бы вы ожидали чего-то от сообщества? – ajreal
Спасибо за предложение. Я не хотел подавлять информацию, но, основываясь на ваших отзывах, я добавил структуры таблиц. – thegreatt
Это тоже не очень полезно, вы должны включить правильную схему, потому что схема будет включать в себя тип данных + индексный тип/столбец – ajreal