表与临时表性能

时间:2009-10-23 18:45:19

标签: sql sql-server tsql sql-server-2008

数百万条记录的速度更快:永久表临时表?

我只能将它用于1500万条记录。处理完成后,我们会删除这些记录。

7 个答案:

答案 0 :(得分:15)

在您的情况下,我们使用称为临时表的永久表。这是大量进口的常用方法。事实上,我们通常使用两个临时表,其中一个包含原始数据,另一个包含清理数据,这使得使用Feed的研究问题变得更容易(它们几乎总是由于我们的客户发现向我们发送垃圾数​​据的新方式和变化方式,但是我们必须能够证明这一点)。另外,您可以避免出现问题,例如必须增加临时数据库或者为其他想要使用临时数据库的用户造成问题,但必须等待它为您增长等等。

您也可以使用SSIS并跳过临时表,但我发现无需重新加载50,000,000表即可返回并进行研究非常有用。

答案 1 :(得分:12)

如果不使用tempdb,请确保您使用的数据库的恢复模型未设置为“完全”。这将导致这些50M行插入的大量开销。

理想情况下,如果可能,您应该在RAID 10上使用临时数据库,简单恢复模型,并提前调整大小以便为所有操作提供足够的空间。关闭自动生长。

使用INSERT ... WITH(TABLOCK)来避免行级日志记录:

INSERT INTO StagingTable WITH (TABLOCK) (.....)
SELECT .....

同样适用于BULK INSERT。如果删除并重新创建,请先创建之前的索引以插入。如果不能,请先插入一个表,然后从中插入具有正确聚类的另一个表,并截​​断第一个表。如果可能,请避免BULK INSERT上的小批量。请仔细阅读BULK INSERT文档,因为您可以使用错误的选项破坏性能。

避免INSERT ... EXEC。记录每一行。

避免更新,除非您需要计算运行总计。通常,从一个表插入另一个表然后截断第一个表比在适当位置更新更便宜。运行总计算是例外,因为它们可以使用UPDATE和变量来累积行之间的值。

避免除控制结构之外的任何表变量,因为它们会阻止并行化。不要将50M行表连接到表变量,而是使用临时表。

不要害怕游标的迭代。使用游标变量,并使用STATIC关键字对聚集索引前面的低基数列进行声明。使用它将大表切成更易于管理的块。

不要试图在任何一个声明中做太多。

答案 2 :(得分:2)

如果表结构要100%相同,则永久表会更快,因为没有分配空间和构建表的开销。

在某些情况下,临时表速度更快(例如,当您不需要永久表中存在的索引时,这会降低插入/更新的速度)

答案 3 :(得分:0)

永久表在大多数情况下比临时表更快。

查看:http://www.sql-server-performance.com/articles/per/derived_temp_tables_p1.aspx

答案 4 :(得分:0)

我个人会在每次使用之前使用永久表并截断它。根据我的经验,它更容易理解/维护。但是,我最好的建议是尝试两者,看看哪一个表现更好。

答案 5 :(得分:0)

要视情况而定。

临时表存储在tempdb数据库中,该数据库可能与实际数据库不在同一驱动器上。因此,很大程度上取决于a)这些驱动器的速度以及b)哪些数据库/文件位于同一驱动器上。
(例如,如果数据库文件和日志文件位于不同的物理驱动器上,则您的实际数据库会更快)


如果使用数据库镜像之类的可用性解决方案,则临时表可能会更快:
在工作中,我们正在使用同步数据库镜像which means that if we write to our database, the data is immediately written to the mirror server as well,并且主服务器在返回调用方(!)之前等待镜像的确认。

因此,如果您将1500万条记录插入表中,对其进行处理(可能涉及全部更新) ,然后将其删除,则SQL Server必须立即在服务器上传播所有这些更改。网络连接到镜像服务器。

另一方面,在临时表中执行此操作将保留在tempdb数据库中的服务器本地。

答案 6 :(得分:-1)

临时表在内存中(除非它们太大),所以理论上它们应该非常快。 但通常不是。 根据经验,尽量远离临时表,除非这是唯一的解决方案。 你能给我们一些关于你想要做什么的更多信息吗?它可能可以使用派生查询来完成