簡體   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