Самый быстрый способ обеспечить ограничение на UserId - PullRequest
0 голосов
/ 18 октября 2019

У меня есть интересная проблема: я хочу установить конкретное ограничение на количество предложений, которые может разместить пользователь. Предложения сохраняются в базе данных postgresql (версия 10) и не должны превышать 1000.

Я использую следующий запрос sql, чтобы проверить, сколько предложений есть у пользователя, и проверить его на предмет ограничения:

select count(*) from offers where offers.userId = 'b27e1d2f-c2c1-4d0b-8451-287013d7b716';

В показателях производительности я вижу, что большая часть времени уходит на этот запрос. Поэтому я посмотрел его и обнаружил следующее: https://wiki.postgresql.org/wiki/Slow_Counting

PostgreSQL все равно нужно будет прочитать полученные строки, чтобы убедиться, что они существуют;

В планировщике запросов этоМожно заметить, что в дополнение к просмотру индекса требуется только выборки кучи , что, как я полагаю, замедляет весь запрос:

Index Only Scan using offers_by_user_id_index on offers
Index Cond: (account_id = 'b27e1d2f-c2c1-4d0b-8451-287013d7b716'::uuid) | Heap Fetches: 650

- Какие способы ускорить это?

Является ли отслеживание количества строк хорошим подходом для ускорения проверки?

Спасибо за вашу помощь!

Редактировать: UserId - это UUID и индекссуществует в столбце UUID

Ответы [ 3 ]

1 голос
/ 19 октября 2019

Количество выборок из кучи говорит о том, что таблица не пылесосится достаточно часто. Если вы вручную VACUUM это, это ускоряет дело?

1 голос
/ 19 октября 2019

Я бы сказал, что правильным инструментом для этого является нормализация:

  1. В таблицу пользователей добавьте столбец offerCount
  2. Создайте индекс по идентификатору пользователя таблицы пользователей, offerCount

Добавить два триггера к предложениям таблицы

  1. Вставить триггер - обновит таблицу пользователей и увеличит столбец offerCount
  2. Удалить триггер - обновит таблицу пользователей и уменьшит столбец offserCount

При этом задержка практически не будет

примечание: если вы не хотите обновлять таблицу пользователя, просто создайте новую, используя только два столбца

0 голосов
/ 18 октября 2019

Во-первых, ваши идентификаторы - это, по-видимому, числа, поэтому сравнение не должно быть строкой. Итак:

select count(*)
from offers
where offers.userId = 1;

Для этого запроса я рекомендую запросить на offers(userid). Это может быть большой помощью.

Это может быть ситуация, когда сохранение идентификаторов в массиве выгодно. Затем вы можете просто добавить:

alter table users add constraint chk_offers check (array_length(offers) <= 1000)

Это также меняет способ вставки и удаления значений.

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

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