Выберите случайные строки в соответствии с заданным критерием PostgreSQL - PullRequest
1 голос
/ 09 апреля 2020

У меня есть таблица user с десятью миллионами строк. Имеет поля: id int4 primary key, rating int4, country varchar(32), last_active timestamp. У него есть пробелы в идентификаторах. Задача состоит в том, чтобы выбрать пять случайных пользователей для данной страны, которые были активны в течение последних двух дней и имеют рейтинг в заданном диапазоне. Есть хитрый способ выбрать их быстрее, чем запрос ниже?

SELECT id
FROM user
WHERE last_active > '2020-04-07'
    AND rating between 200 AND 280
    AND country = 'US'
ORDER BY random()
LIMIT 5

Он подумал об этом запросе:

SELECT id
FROM user
WHERE last_active > '2020-04-07'
    AND rating between 200 AND 280
    AND country = 'US'
    AND id > (SELECT random()*max(id) FROM user)
ORDER BY id ASC
LIMIT 5

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

1 Ответ

0 голосов
/ 10 апреля 2020

Исходя из плана EXPLAIN, ваш стол большой. Около 2 строк на странице. Либо он очень раздутый, либо сами строки очень широкие.

Ключ к хорошей производительности, вероятно, состоит в том, чтобы заставить его использовать сканирование только по индексу, создав индекс, который содержит все 4 столбца, на которые есть ссылки в Ваш запрос. Столбец, проверенный на равенство, должен стоять первым. После этого вам придется выбирать между двумя столбцами, для которых задан диапазон или неравенство («last_active» или «rating»), в зависимости от того, что, по вашему мнению, будет более избирательным. Затем вы добавляете другой диапазон или неравенство и столбец id в конец, чтобы можно было использовать сканирование только по индексу. Так что, может быть, create index on app_user (country, last_active, rating, id). Это, вероятно, будет достаточно.

Вы также можете попробовать индекс GiST для тех же столбцов. Это имеет теоретическое преимущество, заключающееся в том, что два ограничения диапазона или неравенства можно использовать вместе при определении того, какие индексные страницы следует просматривать. Но на практике индексы GiST имеют очень высокие издержки, и эти издержки, вероятно, превысят теоретическое преимущество.

Если вышеприведенное не достаточно хорошо, вы можете попробовать разделить. Но как именно вы это делаете, должно основываться на целостном c представлении вашего приложения, а не на одном запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...