В базах данных Postgres ограничения взаимосвязи снижают производительность?

Это мой первый пост здесь, и я старался делать домашнее задание.

Мне нужен лучший способ разработки баз данных хранилища данных для Postgres, чем использование Power * Architect. Вот полная печальная история:

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

Чтобы смоделировать эту базу данных DW, я должен рисовать диаграммы, и рекомендуется показать, какая таблица к какой относится через внешний ключ / первичный ключ. Увидеть взаимосвязь помогает коммуникация модели с клиентом, а также ее развитие.

Однако большинство разработчиков моделей баз данных, например Power Architect, генерируют код для фактического создания ограничений. Кроме самого изменения кода Power Architect, невозможно помешать ему это сделать.

И вот тут-то и возникает проблема: когда я начинаю развивать модель, всякий раз, когда я проверяю текущую базу данных (которая полностью свободна от взаимосвязей) с моей моделью (которая полна линий взаимосвязей FK), чтобы найти то, что (таблицы, столбцы, индексы), Power * Architect жалуется, что связи отсутствуют, и «любезно» генерирует код для их создания. Мне нужно прочитать diff, выполняя большую фильтрацию разума (пытаясь прочитать код, не принимая команды ограничения добавления), и, применяя diff'd SQL к моей базе данных, я должен вручную удалить эти команды.

Это не было бы проблемой, если бы, как в Oracle, я мог бы приказать Postgres отключить ограничения отношений. Я мог хранить аккуратные диаграммы в Power * Architect, не беспокоясь о действующих в базе данных взаимосвязях. Но я не могу (и никогда не собираюсь переходить на Oracle). Так что моя проблема была бы решена, если бы я мог постоянно оставлять эти ограничения, ЕСЛИ это не сильно ухудшает запросы к базе данных. Я могу иметь дело с некоторой потерей производительности при записи, если она колеблется около или ниже 10% (например, INSERT принимает 1'06 "вместо 1'00").

Итак, вопросы:

«Есть ли какие-либо существенные потери производительности при выполнении большого объема записи, некоторых небольших обновлений и удалений в таблицах Postgres с действующим ограничением связи FK?»

Согласно этим сообщениям, улучшает ли внешний ключ производительность запросов? и http://www.experts-exchange.com/Database/MS-SQL-Server/A_4293-Can-Foreign-key-improve-performance.html, MS SQL Server страдает от снижения производительности при записи и может немного повысить производительность при чтении . Это общее правило? Постгрес ведет себя аналогичным образом? Я осмотрелся и не нашел на него прямого ответа. Этот ответ https://stackoverflow.com/a/83527/3507015 комментирует флаг НЕТ ДЕЙСТВИЙ. Будет ли это работать (я имею в виду, поддерживать отношения без ущерба для производительности)? (У Postgres есть эта опция, но согласно http://www.postgresql.org/docs/8.1/static/ddl-constraints.html, похоже, он не выполняет «никаких действий», но вместо этого не позволяет выполнять какие-либо действия.)

Конечно, было бы лучше иметь дизайнера базы данных с теми же функциями Power * Architect (обратное / прямое проектирование базы данных, сравнение баз данных / моделей и т. Д.), Которые позволяли мне рисовать линии, но не требовать, чтобы они фактически создавались как ограничения, которые я не пробовал. создавать его каждый раз, когда я сравнивал модель с базой данных.

Извините, что в посте слишком длинный, чтобы задать один-единственный вопрос.


person Fábio de Salles    schedule 07.04.2014    source источник
comment
У меня просто вопрос: вы измерили какие-либо существенные потери производительности при действующем ограничении связи FK?   -  person Adriano Repetti    schedule 07.04.2014
comment
При вставке с ограничениями будет некоторое снижение производительности, но вам придется провести собственные измерения, чтобы увидеть, сколько в вашей ситуации.   -  person Mike Stockdale    schedule 07.04.2014
comment
Адриано, нет. Еще не пробовал. Я боялся, что попытка украсть у меня какое-то время. В любом случае это хорошая идея, и я ее оценю. Спасибо!   -  person Fábio de Salles    schedule 07.04.2014
comment
Майк Стокдейл, спасибо!   -  person Fábio de Salles    schedule 07.04.2014


Ответы (1)


Да, это хит производительности.

Если вы insert или update на ссылающейся стороне отношения, PostgreSQL должен выполнить поиск индекса по уникальному ключу, на который указывает ссылка, чтобы убедиться, что соответствующий узел существует. Однако это нужно делать только тогда, когда изменяется фактическое ключевое поле.

Если вы update или delete со стороны, на которую указывает ссылка, PostgreSQL должен выполнить поиск на стороне ссылки каждой связи, указывающей на ключ, убедившись, что ни одна строка в настоящее время не зависит от удаляемой строки, на которую указывает ссылка. Это приводит к ужасно медленному seqscan, если у вас нет индекса на ссылающейся стороне - и в этом случае это все еще поиск по индексу, и вам придется заплатить стоимость поддержки индекса, который в противном случае может вам не понадобиться.

Однако вы можете отключить FK в PostgreSQL. Это триггеры, и, как и любые триггеры, они могут быть отключены. Вы не можете сделать это глобально, вы должны сделать это для каждой таблицы, но вполне вероятно, что ваш инструмент не заметит, что они отключены, и попытается их «исправить».

Имейте в виду, что планировщику запросов PostgreSQL разрешено полагаться на действительность внешних ключей, и если связь не будет принудительной, это может привести к запросам, дающим неверные результаты. На практике я не думаю, что на данном этапе планировщик много делает с FK (только проверка и уникальные ограничения), так что это не имеет особого значения.

person Craig Ringer    schedule 08.04.2014
comment
Замечательный ответ, большое спасибо! Попробую найти больше об отключении триггера RI. Я также постараюсь узнать больше о планировщике запросов, чтобы предупреждать случайные неверные результаты. - person Fábio de Salles; 09.04.2014
comment
О, это своего рода злоупотребление функцией, и это работает только для суперпользователей, но вы можете (в сеансе) SET session_replication_role = replica, что пропустит все триггеры. Обычно вы ALTER TABLE ... DISABLE TRIGGER ALL. - person Craig Ringer; 09.04.2014
comment
Еще раз спасибо, Крейг. Кстати, это злоупотребление остановит автоматическое увеличение SERIALS? Например, если будет добавлена ​​новая строка, ничего не войдет в SERIAL (и / или значения по умолчанию)? - person Fábio de Salles; 17.04.2014
comment
Отключение триггеров сработало так, как я хотел (также это не отключило сериалы). Я мог сохранить отношения и избежать срабатывания реляционного принуждения. Однако у меня есть побочный эффект: я не могу просто усечь таблицу, которая порождает отношения. Я должен использовать каскадный. Поскольку вывод таблицы Pentaho Data Integration (PDI) выполняет только простое усечение, я обошел это с помощью каскада усечения перед обработкой. В целом решение сработало очень хорошо. Еще раз спасибо за так много хороших идей и предложений, Крейг. - person Fábio de Salles; 02.05.2014