Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调试postgresql截断时间的差异?_Sql_Performance_Postgresql_Profiling_Truncate - Fatal编程技术网

如何调试postgresql截断时间的差异?

如何调试postgresql截断时间的差异?,sql,performance,postgresql,profiling,truncate,Sql,Performance,Postgresql,Profiling,Truncate,postgres 8.3/Ubuntu Karmic/32位(在virtualbox中): 持续时间:76.534毫秒语句:truncate audit.users级联 持续时间:0.952毫秒语句:从audit.users中删除 postgres 8.4/Ubuntu lucid/64位(本机,在承载karmic virtualbox的计算机上): 持续时间:1469.271毫秒语句:truncate audit.users级联 持续时间:0.988毫秒语句:从audit.users中删除 因

postgres 8.3/Ubuntu Karmic/32位(在virtualbox中):

持续时间:76.534毫秒语句:truncate audit.users级联 持续时间:0.952毫秒语句:从audit.users中删除 postgres 8.4/Ubuntu lucid/64位(本机,在承载karmic virtualbox的计算机上):

持续时间:1469.271毫秒语句:truncate audit.users级联 持续时间:0.988毫秒语句:从audit.users中删除 因此,DELETE语句几乎是等效的,但是TRUNCATE在一个平台上比在另一个平台上花费的时间长20倍。EXPLAIN在TRUNCATE上似乎不起作用。我怎么知道花了这么长时间

编辑以添加:


上面的示例是在另一个空闲连接打开到数据库,但没有打开的事务或其他活动时采集的。我在一些自动化测试的
拆卸
方法中使用了TRUNCATE,这就是我注意到平台之间速度差异的地方。

TRUNCATE需要一个锁,设置这个锁可能需要一些时间,因为其他事务。尝试使用pg_锁查看发生了什么。

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;

TRUNCATE在PostgreSQL中的工作方式非常敏感,它取决于文件系统删除块的速度,以及当您写入以刷新写缓存时,它是否正确地执行fsync系统调用。我猜这两个系统上的文件系统设置不同。例如,如果Lucid安装使用ext4和Karmic one ext3,这并不奇怪。较新的内核将通过写屏障正确地将fsync调用转换为磁盘缓存刷新;老一点的人让硬盘在写东西的时候对他们撒谎。这对于在崩溃期间保持数据库写入安全来说是一件好事,但从可靠性的角度来看,如果内核做了正确的事情,性能会下降很多。

有没有办法记录锁事件,而不是用pg_锁轮询它们?如果时间<100ms,则很难准确读取锁的数量。在需要更长时间的情况下,峰值时有70多个锁。如果不想等待,请设置不带等待的手动锁:调整log_LOCK_waits如果你想,正如名字所说,log LOCK waits:我编辑了我的问题以提供更多的上下文;我给出的计时不是来自一个具有大量并发性的应用程序,而是来自一个空闲的系统。这很奇怪。我会研究弗兰克建议的即时锁,或者尝试询问PG邮件列表。就是这样。在慢速系统上关闭
fsync=off
,使其与另一个系统一样快。也许virtualbox并没有真正做fsync之类的事情。 duration: 1469.271 ms statement: truncate audit.users cascade duration: 0.988 ms statement: delete from audit.users
begin;

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

delete from data;

insert into data select * from my_data;

commit;