ОБНОВЛЕНИЕ МАТЕРИАЛИЗОВАННОГО ПРЕДСТАВЛЕНИЯ Postgresql ОДНОВРЕМЕННО нарушает порядок

#postgresql #postgresql-9.5 #materialized-views

#postgresql #postgresql-9.5 #материализованные представления

Вопрос:

У меня есть материализованный вид, и это очень полезно. Но после некоторого времени его использования у меня возникла проблема, что порядок в представлении нарушен. Я создал Matview как:

 CREATE MATERIALIZED VIEW mat_view_sorted_products AS
      SELECT item.id, item.category_id FROM item
      INNER JOIN stock ON stock.item_id = item.id
      ORDER BY is_available DESC, views DESC;

CREATE UNIQUE INDEX mat_view_index_id ON mat_view_sorted_products (id);
  

ПОРЯДОК в моем случае очень важен, поэтому он работает, когда я запрашиваю из Matview и получаю отсортированный результат объединения таблиц:

 SELECT id FROM mat_view_sorted_products
LIMIT 100 OFFSET 0; //got 100 sorted item ids by (is_available DESC, views DESC)
  

Для обновления материализованного представления я использую: REFRESH MATERIALIZED VIEW CONCURRENTLY mat_view_sorted_products

Но через некоторое время и множество обновляющих итераций я увидел, что порядок записей matview нарушен. Я думал, что это ОДНОВРЕМЕННО обновляет значения свободных (для чтения) записей и ничего больше не меняет.

Нет? Как это работает и как не нарушать ПОРЯДОК при обновлении представления?

Постскриптум

если я выполняю ОБНОВЛЕНИЕ без ОДНОВРЕМЕННОГО восстановления нормальной сортировки. Он блокирует представление, очищает его и восстанавливает из select с помощью order . Но у пользователей нет времени ждать каждый раз, когда обновляется представление

Обновить:

Конечно, я использую порядок в своем полном операторе ВЫБОРА:

 SELECT id, name, views FROM item WHERE id IN (SELECT id FROM mat_view_sorted_products
LIMIT 100 OFFSET 0) ORDER BY is_available DESC, views DESC;
  

И он выполняет сканирование последовательности в mat_view_sorted_products, и я получил 100 отсортированных элементов всех отсортированных элементов в поле зрения.
Как я думаю, представление создает:

  1. получил 200 элементов, заказанных … из AS SELECT
  2. вставил их в MatView
  3. выполнение сканирования seq для 200 отсортированных элементов, чтобы получить первые 100 отсортированных элементов из всех

Комментарии:

1. Поскольку материализованные представления — это просто таблицы, у них нет порядка. Вы должны указать порядок в своем SELECT запросе.

Ответ №1:

Нет, порядок «не нарушен», потому что в таблице нет такого понятия, как «порядок» строк.

Таблицы (и это включает в себя материализованные представления) представляют неупорядоченные наборы, и они не имеют подразумеваемого порядка.

Единственный способ получить гарантированный порядок сортировки — использовать order by в вашем операторе ВЫБОРА. Альтернативы нет.

Удалите order by из вашего оператора CREATE MATERIALIZED view и добавьте его в свой фактический SELECT оператор. Использование LIMIT или OFFSET без an ORDER BY является ошибкой в вашем коде.

Комментарии:

1. Пожалуйста, следите за обновлением

2. @НиколайАгеев Ваш подзапрос, который использует LIMIT и OFFSET все еще не использует ORDER BY . Порядок by во внешнем запросе не имеет значения для предложений limit и offset

3. Если я вставлю отсортированный результат в новый / чистый вид, зачем мне нужно повторять сортировку записей после него? Сканирование последовательности будет проходить через отсортированную таблицу при выборе из представления

4. Опять же: единственный способ получить гарантированный порядок сортировки — использовать order by . Если вы получили отсортированный результат до сих пор, это было чистое совпадение и могло измениться в любое время, например, когда одновременно выполняются два последовательных сканирования в одной таблице. Единственный способ получить гарантированный порядок сортировки — использовать ORDER BY — альтернативы нет .

5. Поэтому, когда я создаю материализованный вид, мне не нужно использовать ORDER в AS .. (поскольку это бессмысленно), да?