Как отладить различия во времени postgresql TRUNCATE? - PullRequest
2 голосов
/ 19 июля 2010

postgres 8.3 / Ubuntu Karmic / 32-bit (в виртуальной коробке):

  duration: 76.534 ms  statement: truncate audit.users cascade
  duration: 0.952 ms  statement: delete from audit.users

postgres 8.4 / Ubuntu lucid / 64-bit (собственный, на машине, на которой размещен виртуальный ящик karmic):

  duration: 1469.271 ms  statement: truncate audit.users cascade
  duration: 0.988 ms  statement: delete from audit.users

Таким образом, операторы DELETE в значительной степени эквивалентны, но TRUNCATE занимает в 20 раз больше времени на одной платформе, чем на другой. EXPLAIN, похоже, не работает на TRUNCATE. Как мне узнать, что так долго?

Отредактировано, чтобы добавить:

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

Ответы [ 3 ]

4 голосов
/ 25 июля 2010

Способ работы TRUNCATE в PostgreSQL очень чувствителен к тому, насколько быстро ваша файловая система может удалять блоки, а также к тому, правильно ли она учитывает системный вызов fsync при записи для очистки кэша записи. Я предполагаю, что у вас есть разные настройки файловой системы в двух системах. Например, если установка Lucid использует ext4, а Karmic ext3, это неудивительно. Более новые ядра будут корректно превращать вызовы fsync в очистку дискового кэша через барьеры записи; старшие из них позволяют врать им о том, что пишут. Это хорошо с точки зрения обеспечения безопасности записи в базу данных во время сбоя, но производительность сильно падает, когда ядро ​​делает правильные вещи с точки зрения надежности.

2 голосов
/ 19 июля 2010

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

0 голосов
/ 20 июля 2010

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

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

Я не уверен, для чего вам это нужно, но вы можете построить новую «версию» данных для этой таблицы во временную таблицу, а затем (чтобы время блокировки / обновления было как можно короче) выдвинуть ее живой стол с delete + insert as select:

begin;

create temp table my_data on commit drop as
---... lengthy calculation here;

delete from data;

insert into data select * from my_data;

commit;
...