Раздувание индекса по индексу GIN только для таблицы INSERT - PullRequest
0 голосов
/ 21 июня 2019

У меня есть таблица со столбцом, который является массивом hstore. В нотации JSON данные для этого поля выглядят так:

[
  { type: "Pickup", id: "49593034" },
  { type: "User", id: "5903" },
  ...
]

Количество hstore в массиве для одной записи может достигать 10000, хотя может быть и меньше. Эта таблица получает только вставки. Данные не удаляются и не обновляются после добавления записи.

В настоящее время в этой таблице около 90 тыс. Записей, и обычно она будет увеличиваться на несколько сотен каждый день. Значения в более поздних записях, вероятно, будут иметь идентификаторы, отличные от значений в более ранних записях.

Мне нужно выполнить поиск по этому столбцу. Например, я хотел бы знать все записи, где этот столбец включает 'type=>User,id=>5903'::hstore. Я обнаружил, что если я создал индекс GIN для этого столбца и запросил оператор &&, он может быстро найти эти данные.

У меня была проблема, когда раздувание в этом запросе стало очень высоким. PG прекратил использование индекса и переключился на сканирование таблицы, что привело к очень медленной работе. Я исправил это, запустив REINDEX в индексе.

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

Я использую сервис Heroku PG, и они предоставляют инструмент для запроса раздувания. Запрос, который он выполняет, можно найти здесь .

После выполнения REINDEX размер индекса составляет около 1 ГБ. Когда он раздувается, он увеличивается примерно до 11 ГБ, согласно запросу Heroku.

Мои вопросы:

  1. Что именно вызывает вздутие живота? С таблицами я понимаю, что DELETE или UPDATE вызовут вздутие живота. Вызывает ли добавление данных необходимость перебалансировать дерево или что-то, что приводит к мертвым страницам в индексе, или что-то в этом роде?
  2. Точны ли данные из запроса Heroku. Я читал кое-что о некоторых раздуваемых запросах для btrees, а не для индексов джина. Возможно, это указывает на несуществующую проблему. Единственный раз, когда он фактически прекратил использование индекса, это когда я впервые сделал массовую вставку для заполнения таблицы. После этого это раздуло, но продолжало использовать индекс. Может быть, я знаю, что у меня больше нет проблем, и я просто переиндексацию без причины.
  3. Что-то, что я должен изменить в своей схеме, чтобы сделать это обслуживание бесплатным?

Я думал о рефакторинге, чтобы данные в этом столбце сохранялись в отдельной таблице. Эта отдельная таблица будет хранить тип, идентификатор и идентификатор моей основной таблицы в виде отдельных столбцов. Я бы создал индекс btree в поле type и id. Это даст мне вообще безуходный поиск? Я думаю, что это также будет быстрее, поскольку id может быть сохранено как истинное число. В настоящее время он хранится в виде строки, поскольку значения hstore всегда являются строками.

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