У меня есть приложение, в котором пользователи могут выбирать различные интересы из 300 возможных. Каждый выбранный интерес сохраняется в объединяющей таблице, содержащей столбцы user_id и Interest_id.
Обычные пользователи выбирают около 50 интересов из 300.
Я хотел бы создать систему, в которой пользователи смогут найти 20 лучших пользователей, которые имеют с ними самые общие интересы.
Сейчас я могу выполнить это, используя следующий запрос:
SELECT i2.user_id, count(i2.interest_id) AS count
FROM interests_users as i1, interests_users as i2
WHERE i1.interest_id = i2.interest_id AND i1.user_id = 35
GROUP BY i2.user_id
ORDER BY count DESC LIMIT 20;
Однако выполнение этого запроса занимает около 500 миллисекунд с 10 000 пользователей и 500 000 строк в объединяемой таблице. Все индексы и параметры конфигурации базы данных были настроены в меру моих возможностей.
Я также пытался вообще избегать использования объединений, используя следующий запрос:
select user_id,count(interest_id) count
from interests_users
where interest_id in (13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,508)
group by user_id
order by count desc
limit 20;
Но этот еще медленнее (~ 800 миллисекунд).
Как лучше всего сократить время, необходимое для сбора данных такого рода, до значения ниже 100 миллисекунд?
Я подумал о том, чтобы поместить эти данные в графическую базу данных, например Neo4j, но я не уверен, является ли это самым простым решением или оно будет даже быстрее, чем то, что я сейчас делаю.