Индекс силы будет обновлен - PullRequest
0 голосов
/ 25 января 2019

Я передаю права собственности как отношения «Проект -> Владение -> Пользователь», и следующая функция получает имена владельцев проекта в виде текста:

CREATE FUNCTION owners_as_text(projects) RETURNS TEXT AS $$
  SELECT trim(both concat_ws(' ', screen_name, first_name, last_name)) FROM users
    INNER JOIN ownerships ON users.id = ownerships.user_id
    WHERE deleted_at IS NULL AND ownable_id = $1.id AND ownable_type = 'Project'
$$ LANGUAGE SQL IMMUTABLE SET search_path = public, pg_temp;

Затем используется для построения индекса, который игнорирует акценты:

CREATE INDEX index_projects_on_owners_as_text
  ON projects
  USING GIN(immutable_unaccent(owners_as_text(projects)) gin_trgm_ops)

Когда проект обновляется, этот индекс также обновляется. Однако, когда, например, имя владельца меняется, этот индекс не будет затронут, верно?

Как я могу заставить индекс обновляться на регулярной основе, чтобы наверстать упущенное в этом случае?

(REINDEX не вариант, так как он блокируется и вызывает взаимные блокировки, если действия записи происходят одновременно.)

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Поскольку вы солгали PostgreSQL, сказав, что функция была IMMUTABLE, когда она на самом деле STABLE, неудивительно, что индекс изменяется при изменении базы данных.

Решением является , а не для создания такого индекса.

Лучше не использовать эту функцию, а использовать представление, в котором есть выражение, которое вы хотите найти в виде столбца. Затем можно оптимизировать запрос, использующий представление, и использовать индекс immutable_unaccent(btrim(concat_ws(' ', screen_name, first_name, last_name))).

Вероятно, можно обмануть изменчивость unaccent ...

0 голосов
/ 25 января 2019

Идея ошибочно принята, потому что индекс построен на функции, которая на самом деле не является неизменной. Для документации:

IMMUTABLE указывает, что функция не может изменить базу данных и всегда возвращает один и тот же результат, если даны одинаковые значения аргумента; то есть он не выполняет поиск в базе данных или иным образом не использует информацию, прямо не представленную в списке аргументов.

Проблемы, с которыми вы сейчас сталкиваетесь, возникают из-за неверных предположений.

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