Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.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
Sql 表与临时表性能_Sql_Sql Server_Tsql_Sql Server 2008 - Fatal编程技术网

Sql 表与临时表性能

Sql 表与临时表性能,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,对于数百万条记录,哪一条更快:永久表还是临时表 我只能用它来记录1500万张唱片。处理完成后,我们将删除这些记录。如果表结构100%相同,则永久表的速度更快,因为分配空间和构建表没有开销 临时表在某些情况下速度更快(例如,当您不需要永久表上的索引,这会减慢插入/更新速度时)临时表在内存中(除非它们太大),因此理论上它们应该非常快。 但通常不是这样。 根据经验,尽量远离临时表,除非这是唯一的解决方案。 你能告诉我们更多关于你想做什么的信息吗?它可能是通过派生查询来完成的。在大多数情况下,永久表比临

对于数百万条记录,哪一条更快:永久表还是临时表


我只能用它来记录1500万张唱片。处理完成后,我们将删除这些记录。

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

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

临时表在内存中(除非它们太大),因此理论上它们应该非常快。 但通常不是这样。 根据经验,尽量远离临时表,除非这是唯一的解决方案。
你能告诉我们更多关于你想做什么的信息吗?它可能是通过派生查询来完成的。在大多数情况下,永久表比临时表更快


看看:

在您的情况下,我们使用一个名为暂存表的永久表。这是大量导入的常用方法。事实上,我们通常使用两个暂存表,一个包含原始数据,另一个包含清理后的数据,这使得研究提要问题变得更加容易(它们几乎都是我们的客户发现的向我们发送垃圾数据的各种新方法的结果,但我们必须能够证明这一点)。此外,您还可以避免诸如必须增加temp db或为其他希望使用temp db但必须在temp db为您增长时等待的用户带来问题等问题


您也可以使用SSI并跳过暂存表,但我发现,无需重新加载50000000表即可返回并进行研究的功能非常有用。

我个人会使用永久表,并在每次使用前将其截断。根据我的经验,它更容易理解/维护。但是,我给您的最好建议是,两种方法都尝试一下,看看哪一种性能更好。

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

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

使用插入。。。使用(TABLOCK)避免行级日志记录:

INSERT INTO StagingTable WITH (TABLOCK) (.....)
SELECT .....
批量插入也是如此。如果删除并重新创建,请在插入之前创建聚集索引。如果不能,请先插入一个表,然后从该表插入另一个具有正确集群的表,并截断第一个表。如果可能,避免批量插入的小批量。仔细阅读大容量插入文档,因为使用错误的选项可能会破坏性能

避免插入。。。执行官。每一行都被记录下来

避免更新,除非您需要计算运行总数。通常,从一个表插入到另一个表,然后截断第一个表比就地更新要便宜。运行总计计算是例外,因为它们可以通过更新和变量在行之间累积值来完成

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

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

不要试图在任何一句话中做得太多。

视情况而定

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


如果使用数据库镜像之类的可用性解决方案,临时表可能会更快:
在工作中,我们使用的是同步数据库镜像,主服务器在返回调用方之前等待镜像的确认(!)

因此,如果在表中插入1500万条记录,并对其进行处理(可能涉及对所有记录的一些重大更新),然后将其删除,SQL Server必须立即通过网络将所有这些更改传播到镜像服务器


另一方面,在temp表中执行此操作将在服务器上的
tempdb
数据库中保持本地状态。

这在很大程度上取决于具体情况。你想用它做什么?永久表。你连接到服务器,百万记录已经存在,无需任何操作,亚纳米秒时间。。。也许你想详细说明你的问题?我要处理5000万条记录。为此,我必须创建永久/临时表。场景是:为了处理5000万条记录,我创建了另一条?/?表并插入到该表中。然后我将优先级应用为(Fname),并将其插入另一个永久\temp表中,然后从第一个表中删除。并应用优先级2,然后再次执行第一步。所以我问了这个问题。请回答。临时变量存储在内存中,而不是临时表。我没有看到问题是针对MSSQL的。在MySQL中,您可以声明一个临时内存表:
CREATE temporary table test ENGINE=memory
表变量显然也存储在tempdb中-请参阅SSIS可能是最好的解决方案+1,以指出在发生错误时查看暂存数据的附加好处--“您还可以使用SSIS并跳过暂存表”,但我发现不必重新加载50000000个表就可以返回并进行研究是非常有帮助的。”非常好且令人满意的回答。Thanx对于所有这一切,只有当进程是单例的,并且在此期间没有任何其他进程启动的机会,并且也需要使用该表时,这才有效。我们有每天导入大量数据的流程