Ric*_*don 6 postgresql postgresql-performance
我有一个语句正在将一堆行(这个问题的内容或位置并不重要)插入到 Postgres 数据库中,但它没有我想要的那么快。我可以运行一个解释查询来查看它在做什么,我得到如下结果:
Insert on dpdb.datapoints (cost=0.00..6917.76 rows=44184 width=1786) (actual time=15558.623..15558.623 rows=0 loops=1)
Buffers: shared hit=34670391 read=98370 dirtied=48658 written=39875
I/O Timings: read=704.525 write=242.915
-> Seq Scan on public.fred (cost=0.00..6917.76 rows=44184 width=1786) (actual time=0.018..197.853 rows=44184 loops=1)
Output: nextval('datapoints_id_seq'::regclass), fred.company_id, fred.tag, ... lots more columns ...
Buffers: shared hit=44186 read=6253 dirtied=1
I/O Timings: read=29.176
Planning time: 0.110 ms
Trigger RI_ConstraintTrigger_c_14845718 for constraint datapoints_tag_source_fkey: time=236.677 calls=44184
Trigger RI_ConstraintTrigger_c_14845723 for constraint datapoints_sheet_type_fkey: time=536.367 calls=44184
Trigger RI_ConstraintTrigger_c_14845728 for constraint datapoints_subcontext_fkey: time=178.200 calls=44184
Trigger RI_ConstraintTrigger_c_14845733 for constraint datapoints_source_type_fkey: time=467.619 calls=44184
Trigger RI_ConstraintTrigger_c_14845738 for constraint datapoints_doc_type_fkey: time=302.256 calls=44184
Trigger RI_ConstraintTrigger_c_14845743 for constraint datapoints_comment_type_fkey: time=88.740 calls=44184
Trigger RI_ConstraintTrigger_c_14845748 for constraint datapoints_preferred_dpid_fkey: time=33.313 calls=44184
Execution time: 17432.381 ms
(16 rows)
Run Code Online (Sandbox Code Playgroud)
这很棒,因为我可以看到各种触发器和查询的选择部分的成本,但如果我将所有这些部分加起来,大约需要 2 秒(不到总时间的 10%)。除了花费了大约 24 秒之外,它并没有告诉我太多有关实际插入的信息。我猜测成本的相当一部分是更新索引,但我不确定这一点。如何详细了解正在更新哪些索引以及每个索引的相对成本?这可能吗?
(我最初在 dba.stackexchange.com 上问过这个问题,但没有得到任何答案 - 它介于 DBA 和开发问题之间,所以我想我应该在这里问)
这些看起来像是外键约束。每个插入都会执行SELECT检查以查看该行是否存在,希望使用索引假设索引存在。
时间差异是因为time每个触发器都会显示执行该函数所花费的时间,并且不包括 IO 等待时间。换句话说,它不是向您显示挂钟时间,而是显示 CPU 时间(大约)。
您可以使用pg_stat_statements尝试查看针对这些表的查询并找到外键,但最终这对于使用外键来说看起来很正常。
如果您需要这些插入更快地执行,最好的选择是删除外键约束。
| 归档时间: |
|
| 查看次数: |
3077 次 |
| 最近记录: |