正如您所见,有很多方法可以运行更新过程,哪种更好取决于此处未介绍的因素。首先让我们澄清一下 TEMP 表是什么,并将其与临时表区分开来。临时表仅在当前会话(连接)处于活动状态时才存在。如果连接断开,那么 TEMP 表也会断开。暂存表是用于暂存数据的永久表,它与您描述的问题部分更接近。我将使用这两个术语来明确正在制作的内容(TEMP 或 staging)。
您的问题围绕着在 ETL(ELT?)过程中使用一系列表来提高(我预计)可诊断性/调试能力的性能影响有多大。这是一个很好的目标,但与现实世界中的所有权衡一样,也有一些缺点。
如果这是正确的,这些表将需要临时表,因为 TEMP 表将在 ETL 会话结束时消失。
在可以使用时保存一堆临时表有一些缺点,但它们有多大取决于您的情况。如果您的集群相当空闲并且 ETL 数据负载不是很大,那么额外表对 ETL 过程的影响将是真实的,但不会很大(几秒钟或更短)。这些影响主要围绕设置(或截断)暂存或 TEMP 表。但是,如果您的集群在 ETL 运行时正在运行其他工作负载,那么影响可能会更大。
您会看到 Redshift 集群中有许多“资源”,它们都需要由数据库上运行的所有内容共享。一些类似的内存分配可以(在某种程度上)通过 WLM 进行控制。其他人不能。两大巨头是网络带宽和磁盘带宽。 Redshift 中这些带宽的容量是固定的,即使它们很高,它们也是有限的。 Redshift 执行总工作负载的能力还有其他限制,但根据我的经验,这是最大的两个。
每次创建临时表或永久表时,数据都会存储到磁盘中。这意味着写入磁盘以及根据表的分布设置分布数据。然后,当访问表时,需要从磁盘读取数据。所有这些不必要的数据移动都会产生一些影响,大小将取决于它有多大以及当时正在发生的其他事情。因此,您会看到影响将适度小到非常大,具体取决于许多因素,其中最重要的是您要创建多少表。这样做的成本需要通过拥有这些额外表格的好处来抵消,这是一项业务决策。
一种常见的模式是将数据加载 (COPY) 到临时表或临时表,然后将 DELETE 模式提取到一个临时表,并将 INSERT 数据提取到另一个。一旦应用了删除和插入,然后保存这些表,并在名称中带有日期戳,并可能卸载到 S3。一段时间后这些数据集被删除,1个月是常见的。这样,如果事情发生横向变化,您就可以弄清楚“发生了什么”。这加上良好的数据库备份可用于从代码错误中恢复。
您的第二个问题是删除并重新创建还是截断更好。这两个语句都有许多性能改进。带着一粒盐,我将提供我比较这些的稍微过时的经验。两者都很快,但我看到 drop 和 recreate 的速度稍快(需要管理的依赖项更少)。也就是说,主要区别在于它们如何与数据库的其他方面进行互操作。如果存在依赖视图(除非级联)并且表权限将丢失,则 DROP 将失败。 DROP 不能在事务块中运行,并且由于它需要对表进行排他锁,因此可以将读取表的另一个会话推迟。 TRUNCATE 可以在事务块中运行,但会强制提交,因此事务更改将对所有人可见。通常正是这些差异决定了 TRUNCATE 还是 DROP,还有其他选项,例如 DELETE 和 ALTER TABLE APPEND,它们各有优缺点。
因此,当权衡所有需求(包括性能和业务需求)时,我通常建议不要在 ETL 流程中创建比实际需要更多的表。您现在可能有多余的容量,但随着时间的推移,Redshift 集群通常会变得更加繁忙。这里的指导原则是移动大量数据的次数不要超过必要的次数。