Как отключить все ограничения в моем postgresql?

У меня есть база данных PostgreSQL с таблицами, содержащими более 500 миллиардов строк. Я пытаюсь удалить около 6 миллионов строк, но это занимает более 4 минут. Мне нужно оптимизировать эту операцию удаления, чтобы сделать полезную систему.

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

Как отключить все ограничения? И можно ли отключить отношения между таблицами?

Прямо сейчас я просто отключаю триггеры, используя это:

Alter table "table_name" disable all

И включите его обратно, используя это:

Alter table "table_name" enable all

Редактировать

Это результат запроса с включенными триггерами.

  Delete on "ParameterValues"  (cost=0.00..1015910.71 rows=47196359 width=6) (actual time=296995.938..296995.938 rows=0 loops=1)
  Buffers: shared hit=6000000 read=420811 dirtied=93346 written=51646
  ->  Seq Scan on "ParameterValues"  (cost=0.00..1015910.71 rows=47196359 width=6) (actual time=7977.126..19798.361 rows=6000000 loops=1)
        Filter: ("Id" < 23000000)
        Rows Removed by Filter: 34218414
        Buffers: shared read=420811 dirtied=49228 written=51646
Planning Time: 304.085 ms
Execution Time: 296995.963 ms

Отключив все триггеры, я улучшил производительность, сократив время выполнения с 5 до 3 минут.

Alter table "table_name" disable trigger all

Однако мне нужно улучшить больше операций удаления. Есть идеи?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
2 004
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если вам нужно чистое решение pl/pgsql. вы можете использовать такой анонимный блок (или даже функцию с именем таблицы и схемой в качестве аргументов).

DO $$
DECLARE 
l_tab_name    TEXT := 'yourtablename';
l_schema_name TEXT := 'public';
rec record;

BEGIN
for rec IN
(
SELECT rel.relname as table_name ,con.conname as constraint_name
       FROM pg_catalog.pg_constraint con
            INNER JOIN pg_catalog.pg_class rel
                       ON rel.oid = con.conrelid
            INNER JOIN pg_catalog.pg_namespace nsp
                       ON nsp.oid = connamespace
       WHERE nsp.nspname     = l_schema_name
             AND rel.relname = l_tab_name
)
  LOOP

       EXECUTE format ('ALTER TABLE %I 
                        DROP CONSTRAINT %I',rec.table_name,rec.constraint_name );

  END LOOP;
END $$;

Я получил 0 обновленных строк. Я просто взял ваш код и заменил значение l_tab_name именем моей таблицы.

jorgegarciax2 28.05.2019 08:46

@ Хорхе Гарсия: это не то, как вы что-то проверяете. Сначала используйте тестовую таблицу с различными ограничениями. После успешного запуска этого блока опишите таблицу и проверьте, видите ли вы те же ограничения.

Kaushik Nayak 28.05.2019 08:49
Ответ принят как подходящий

Правильный оператор для отключения всех триггеров в таблице:

ALTER TABLE atable DISABLE TRIGGER ALL;

Это отключит все триггеры и ограничения внешнего ключа, определенные для таблицы, поскольку ограничения внешнего ключа реализуются системными триггерами в PostgreSQL.

Он также отключит первичный ключ отложенный, ограничения уникальности и исключения, которые также реализуются с помощью триггеров. Неотложенные ограничения первичного ключа, уникальности и исключения не имеют связанных триггеров и не затрагиваются.

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

Альтернативный способ отключить ограничения на основе триггера — установить для параметра session_replication_role значение replica, что также требует привилегий суперпользователя.

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

Для справки см. документацию ИЗМЕНИТЬ ТАБЛИЦУ.

Когда я использую оператор отключить все триггеры, я получил 0 обновленных строк. Кроме того, время удаления такое же, как и раньше. Я собираюсь проверить ваш вариант.

jorgegarciax2 28.05.2019 08:59
ALTER TABLE не изменяет никаких строк, так что этого следовало ожидать. Если вы не видите увеличения скорости, то, вероятно, это не ваше узкое место. Возможно, это ввод-вывод. Выясните узкое место до, которое вы пытаетесь настроить.
Laurenz Albe 28.05.2019 09:12

это странно, потому что сервер PostgreSQL имеет 500 ГБ SSD, 32 ГБ оперативной памяти и процессор Intel Xeón, совместно используемый с другими виртуальными машинами.

jorgegarciax2 28.05.2019 09:32

Без анализа узкого места вы сведетесь к догадкам.

Laurenz Albe 28.05.2019 09:33

Я думаю, что мое ограничение, первичные ключи и т. д. Не подлежат отсрочке, потому что Entitiy-framework по умолчанию создает все в Не откладываемом. Вероятно, по этой причине я не вижу никакого улучшения скорости.

jorgegarciax2 28.05.2019 10:08

Определенно, это не аппаратная проблема.

jorgegarciax2 29.05.2019 09:58

Как я уже сказал, попробуйте удалить и заново создать ограничения (возможно, в той же транзакции, что и нагрузка) и посмотреть, купит ли это вам что-то.

Laurenz Albe 29.05.2019 10:00

Наконец, я настроил свою установку postgis и теперь могу удалить 6 миллионов строк за 45 секунд. Как вы думаете, это хорошее выступление или, может быть, я мог бы улучшить его еще больше?

jorgegarciax2 29.05.2019 15:32

Если он достаточно быстр для вас, берите его.

Laurenz Albe 29.05.2019 18:34

Это лучше, чем раньше, но я не уверен, что это лучшая производительность, которую я могу получить от PostgreSQL.

jorgegarciax2 29.05.2019 21:28

Еще одна вещь для ускорения модификации данных — установить max_wal_size довольно высоким.

Laurenz Albe 29.05.2019 23:04

Другие вопросы по теме