Как я могу отключить все ограничения в моем postgresql? - PullRequest
2 голосов
/ 28 мая 2019

У меня есть база данных 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

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

Ответы [ 2 ]

3 голосов
/ 28 мая 2019

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

ALTER TABLE atable DISABLE TRIGGER ALL;

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

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

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

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

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

Для справки см. Документацию ALTER TABLE .

1 голос
/ 28 мая 2019

Если вы хотите чистый раствор 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 $$;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...