DROP и CREATE против DELETE и INSERT в PostgreSQL - PullRequest
5 голосов
/ 11 августа 2011

Я должен дублировать значения из одной таблицы в другую (идентичные схемы таблиц).Что лучше (производительность):

  • Удалить таблицу1 и создать как выберите * из таблицы2
  • Удалить все строки из таблицы1 и вставить все строки из таблицы2

Обновление: я сделал небольшой тест для таблицы с почти 3k строк.Удаление и создание дает около 60 мс против удаления и вставки - около 30 мс.

Ответы [ 3 ]

14 голосов
/ 11 августа 2011

Я вижу четыре полезных способа заменить содержимое таблицы.Ни один из них не является «очевидно правильным», но это зависит от ваших требований.

  1. (в одной транзакции) DELETE FROM foo; INSERT INTO foo SELECT ...

    Pro: Лучший параллелизм: не блокирует другие транзакции, обращающиеся к таблице, поскольку он использует MVCC Postgres.

    Con: Вероятно, самый медленный, если вы измеряете только скорость вставки.Заставляет автоочистку очищать мертвые строки, создавая тем самым более высокую нагрузку ввода / вывода.

  2. TRUNCATE foo; INSERT INTO foo SELECT ...

    Pro: Самый быстрый для небольших таблиц,Вызывает меньшее количество операций ввода-вывода при записи, чем # 1

    Con: Исключает все другие считыватели - другие операции чтения из таблицы будут ждать.

  3. TRUNCATE foo, УДАЛИТЬ все индексы в таблице, INSERT INTO foo SELECT ..., заново создать все индексы.

    Pro: Самый быстрый для больших таблиц, потому что создание индексов с CREATE INDEX быстреечем их постепенное обновление.

    Con: То же, что # 2

  4. Переключение.Создайте две идентичные таблицы foo и foo_tmp

    TRUNCATE foo_tmp;
    INSERT INTO foo_tmp SELECT ...;
    ALTER TABLE foo RENAME TO foo_tmp1;
    ALTER TABLE foo_tmp RENAME TO foo;
    ALTER TABLE foo_tmp1 RENAME TO foo_tmp;
    

    Благодаря транзакционным возможностям DDL PostgreSQL, если это происходит в транзакции, переименование выполняется без уведомления других транзакций.Вы также можете комбинировать это с # 3 и удалять / создавать индексы.

    Pro: Меньше операций ввода-вывода, таких как # 2, и без блокировки других считывателей (блокировки выполняются только во времяпереименовать часть).

    Con: Самое сложное.Также вы не можете иметь внешние ключи или представления, указывающие на таблицу, так как они будут указывать на неверную таблицу после переименования.

2 голосов
/ 11 августа 2011

Используйте TRUNCATE вместо DROP TABLE или DELETE, когда вам нужно избавиться от всех записей в таблице. С TRUNCATE вы по-прежнему можете использовать триггеры в PostgreSQL, а разрешения проще устанавливать и поддерживать.

Как и DROP, TRUNCATE также нужна блокировка таблицы.

1 голос
/ 11 августа 2011

Если вы говорите о выполнении INSERT вручную, один за другим, тогда DROP / CREATE будет намного быстрееКроме того, при использовании CREATE TABLE AS он будет только копировать определения столбцов.Индексы и другие ограничения будут не скопированы.Это ускорит процесс копирования чрезвычайно .Но вы должны будете помнить, чтобы воссоздать их на новой копии, как только вы закончите.Они функционально идентичны.У них просто разные имена.

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

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