У меня есть база данных с более чем 100 миллионами строк данных комментариев Reddit в формате:
{
author: redditauthor1,
body: example comment,
subreddit: /r/funny,
....
}
Я пытаюсь получить список пользователей с соответствующим количеством комментариев для всех подредактов, которые они опубликовано в. Я также ограничиваю его пользователями, которые также разместили в подредите, который я передаю в качестве параметра.
У меня есть 4 индекса для этой таблицы. Причина в том, что я пока только планирую читать из этого. Индексы выглядят так:
CREATE INDEX idx_subreddit
ON comments(subreddit);
CREATE INDEX idx_author
ON comments(author);
CREATE INDEX idx_authsub
ON comments(author, subreddit);
CREATE INDEX idx_subauth
ON comments(subreddit, author);
Я также пытался просто сузить его до индекса subreddit, автора без каких-либо улучшений. Я еще больше сужаю свой поиск, удаляя [удаленных] пользователей из списка строк. Мой запрос выглядит следующим образом:
SELECT author, subreddit, count(*) as numcomments
from comments
WHERE author IN (SELECT author FROM comments WHERE subreddit="politics" AND author != "[deleted]")
group by author, subreddit
ORDER BY author
LIMIT 100
;
Согласно моему плану объяснения, это возвращает 3 миллиона строк, что ожидается от набора данных почти 100 ГБ.
Запрос выполняется более 300 секунд для больших поддредитетов, таких как / r / policy . Меньшие с меньшей активностью запускаются в секунду или меньше. Что я могу сделать, чтобы улучшить время выполнения? Я попытался выполнить запрос через Ever SQL и использовать указанный запрос, а также один подредит , автор составной индекс, который они рекомендовали, но на самом деле это ухудшило время выполнения. Я знаю, что есть сторонние варианты, такие как pushShift API, который использует Google BigQuery, но, поскольку я хотел бы работать над этим в автономном режиме, я хочу сделать все это локально. Наконец, я подумал о том, чтобы просто получить все комментарии и «посчитать» их самому, вместо того, чтобы использовать метод и группу mySql count (*), но даже при этом для получения всех комментариев требуется время (15 миллионов). ) что я должен был бы обработать на заднем конце. Есть ли этому решение? Что-то вроде системы кеширования Redis? Разметка? Я бы sh, чтобы получить этот запрос менее 3 секунд, если это возможно. Любые отзывы приветствуются.
По предложению пользователя я выполнил объяснение по этому запросу:
SELECT x.author
, x.subreddit
, COUNT(*) numcomments
FROM comments x
JOIN
( SELECT author
FROM comments
WHERE subreddit = "politics"
AND author != "[deleted]"
) y
ON y.author = x.author
GROUP
BY x.author
, x.subreddit;
и ОБЪЯСНЕНИЕ произвело это: