繁体   English   中英

SQL Server表性能比较-临时表还是表变量? 或者是其他东西?

[英]SQL Server table perf comparison — temp tables, or table variables? Or something else?

在SQL Server中,我试图在给定不同键的情况下针对插入性能对两个不同的表结构进行比较分析。 我是否使用表变量进行此测试是否重要,还是应该使用临时表? 还是我需要麻烦地创建表和索引?

具体来说,我目前正在使用以下脚本:

 DECLARE @uniqueidentifierTest TABLE ( --yes, this is terrible, but I am looking for numbers on how bad this is :) tblIndex UNIQUEIDENTIFIER PRIMARY KEY CLUSTERED, foo INT, blah VARCHAR(100) ) DECLARE @intTest TABLE ( tblindex INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, foo INT, blah VARCHAR(100) ) DECLARE @iterations INT = 250000 DECLARE @ctrl INT = 1 DECLARE @guidKey UNIQUEIDENTIFIER DECLARE @intKey INT DECLARE @foo INT = 1234 DECLARE @blah VARCHAR(100) = 'asdfjifsdj fds89fsdio23r' SET NOCOUNT ON --test uniqueidentifier pk inserts PRINT 'begin uniqueidentifier insert test at ' + CONVERT(VARCHAR(50), GETDATE(), 109) WHILE @ctrl < @iterations BEGIN SET @guidKey = NEWID() INSERT INTO @uniqueidentifierTest (tblIndex, foo, blah) VALUES (@guidKey, @foo, @blah) SET @ctrl = @ctrl + 1 END PRINT 'end uniqueidentifier insert test at ' + CONVERT(VARCHAR(50), GETDATE(), 109) SET @CTRL = 1 --test int pk inserts PRINT 'begin int insert test at ' + CONVERT(VARCHAR(50), GETDATE(), 109) WHILE @ctrl < @iterations BEGIN INSERT INTO @intTest (foo, blah) VALUES (@foo, @blah) SET @ctrl = @ctrl + 1 END PRINT 'end int insert test at ' + CONVERT(VARCHAR(50), GETDATE(), 109) SET NOCOUNT OFF 

如果要比较实际性能,则需要创建表和索引(以及其他所有涉及的内容)。 尽管临时表比表变量要好得多,但是如果您要寻找性能指标,它们都不能替代实际的永久表结构。

所有这一切都这样说,但是,你应该避免使用uniqueidentifier作为主键,或者,至少是,使用newsequentialid()而非newid() 具有聚集索引意味着实际上将按物理顺序存储行。 如果插入的值不正确,则SQL Server必须重新排列行才能将其插入到正确的位置。

首先,在使用newid() ,永远不要将其聚集在uniqueidentifier上,这将导致碎片化,从而导致页面拆分,如果必须使用GUID,则应这样做

create table #test (id uniqueidentifier primary key defualt newsequentialid())

newsequentialid()不会导致页面拆分

与PK相比,int仍然更好,因为现在所有非聚集索引和外键都将变小,并且现在您需要更少的IO来获得相同数量的行

我不知道为什么,但我想引用Remus Rusanu [1]:

首先,您需要在每个[审查者]下重复运行查询并取平均结果,并丢弃具有最大时间的查询。 这将消除缓冲区预热的影响:您希望所有运行都在预热缓存上,而不需要一个查询预热缓存并进行比较。

接下来,您需要确保在实际的并发场景下进行度量。 如果您要在现实生活中进行更新/插入/删除操作,则必须将它们添加到测试中,因为它们将在各种隔离级别下极大地影响读取。 您想要做的最后一件事是得出结论:“可序列化的读取速度最快,可以在任何地方使用它们”,然后看着系统在生产中崩溃,因为所有内容都已序列化。

1)在冷缓存上运行查询不准确。 生产查询将不会在冷缓存上运行,您将优化一个不切实际的方案,并且不评估查询,而是评估磁盘读取吞吐量。 您还需要衡量热缓存上的性能,并跟踪两者(冷运行时间,热运行时间)。

对于大型查询(数以百万计的行)而言,高速缓存在正常情况下仅对特定数据运行一次的相关性如何? 还是很相关的。 即使数据量太大,以至于它永远无法容纳在内存中,并且每次运行都必须重新读取表的每个页面,但仍然会缓存非叶页面(即表中的热页面,根目录或接近根目录的页面) ),较窄的非聚集索引的缓存,表元数据的缓存。 不要以为您的表是ISAM文件

[1]为什么更好的隔离级别意味着SQL Server中更好的性能
为什么更好的隔离级别意味着更好的SQL Server性能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM