我在db.x2g.2xlarge
实例上的 Aurora PostgreSQL 上运行。简单地创建临时表显示为第三高的等待,这让我感到惊讶,因为我预计它是最短的查询之一。
该查询在事务中调用:
CREATE TEMP TABLE identifiers_to_resolve (
scheme_pk BIGINT,
host_pk BIGINT,
port INT NOT NULL,
scheme_specific_part VARCHAR NOT NULL,
index INTEGER NOT NULL
) ON COMMIT DROP;
我想在更复杂的查询期间使用临时表作为事务中临时存储。
来自性能洞察的统计数据:
- 等待负载 (AAS):0.42
- 调用/秒:123.64
- 批量点击/秒:48499.58
- 块写入/秒:16.32
- 每次调用的平均延迟毫秒:3.24
- 批量点击/跟注 329.27
- 块写入/调用 0.13
所有其他统计数据均为 0。
性能洞察将等待记录为几乎所有“CPU”。附截图。
我认为每秒 123 次调用是相当低的速率,而且我很惊讶它对数据库造成了如此大的负担,并触及了这么多块。从我阅读的临时表用例来看,我预计它们的影响较小。
创建临时表是否会导致如此多的 CPU 等待?
将我的评论总结为答案:
创建和销毁临时表涉及文件和系统目录操作,这需要时间。
在上面的示例中,这在临时表创建时可见,而且在提交时、删除时也可见。
使用“提交时删除行”创建的更“永久”的临时表避免了大多数这些操作,因为它在事务结束时被简单地截断。跳过表的创建和删除,因此速度要快得多。
如果您使用连接池,则可以在连接打开时创建临时表,并保留它们以供该连接的所有后续使用。只需使用“ON COMMIT DELETE ROWS”创建它们,这样表就会在每次使用后被截断。
如果您的池在获取已打开的连接并将其传递给客户端时使用DISCARD ALL ,这也会删除临时表,因此应该更改它。不幸的是,没有办法用一个命令丢弃除临时表之外的所有内容,并且在重用连接时保留某些状态通常不是一个好主意,因此这需要一些思考。
当多个连接创建同名的临时表时,它们不是同一个表。它们具有相同的名称,但每个临时表仅存在于打开它的连接的系统目录中,并且每个临时表都有自己的磁盘文件。
因此,他们看不到彼此的行的原因不是由于事务可见性规则......而仅仅是因为它们是不同的表。