每天截斷的表的索引優化
我在 SQL Server 2012 中有一堆表。
這些表由其他表提供。每天都有常式截斷(完全刪除)它們並執行將結果插入其中的查詢。它們就像靜態視圖,儲存那些處理過的數據,以便更快地查詢它們。
並且有源表,每天接收數百萬條新記錄,這些不會被刪除。
所有這些表都有一段時間會收到很多插入,而在一天的其餘時間裡,它們只會被讀取。
即使使用這些“靜態視圖”表,我認為我也可以提高整體性能。是否有任何最佳實踐來處理這些行為?
對於第一種情況,我執行了一些基準測試,發現最佳性能來自對過濾次數最多的欄位使用非聚集索引。我在截斷之前刪除這些索引並在插入後重新創建它們。刪除和重新創建比重建更快,插入也更快。
我也應該保留 PK(沒有語義含義)和聚集索引嗎?我想如果沒有索引,這些插入會更快,但是如果這些表沒有 PK,我會有什麼問題嗎?它們從不明確使用。
我問這個是因為當我創建表並設置它的 PK 時
idBenchmark int NOT NULL IDENTITY (1,1) PRIMARY KEY
聚群索引是自動創建的,具有隨機名稱,因此我無法刪除並重新創建它。
在導入數據時繼續刪除集群鍵。完成後
INSERTs
,首先創建集群鍵,然後是非集群的 PK,然後是任何剩餘的索引。我此時正在執行這樣的腳本,它所花費的時間大約是插入完全索引的表的一半。在載入數據時沒有集群鍵沒有問題。如果可能的話,我建議您按照與集群相同的順序導入數據;這將減少集群時對數據進行洗牌的需要。如果您使用的是任意
IDENTITY
列,我建議您重新考慮;可能有更好的分群候選者(或者您甚至可能不需要分群鍵)。載入數據時沒有PK沒有問題。這對於保持引用完整性和為您的索引提供一個狹窄的目標是最重要的;假設您相信您的數據不包含重複數據,則在您批量載入數據時兩者都不適用。
重複也不總是魔鬼,在批量載入後刪除它們可能比在前端建構以其他方式重複數據刪除的程序更快。
我的偏好是首先將所有醜陋的原始數據提取到堆表中,然後在將其複製到新表之前進行 SQL 清理。也許這只是因為我是一個 SQL 人,對我來說一切都像是釘子,但 SQL針對基於集合的操作進行了優化*。*另一方面,如果數據量很大,您可能需要在通過 SSIS 或其他方式導入數據時基於 RBAR 進行轉換和清理。
我還建議
ALTER TABLE
在您的CREATE TABLE
. 這提醒您做出明確的選擇(包括是否在 PK 上分群),將其放在您的其他索引聲明旁邊,並讓您給它一個非隨機名稱。
如果將集群主鍵添加為單獨的約束,則可以指定它的名稱:
CREATE TABLE dbo.YourTable ( idBenchmark int NOT NULL IDENTITY (1,1), .... other columns .... CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED(idBenchmark) )
然後,如果需要,您應該可以毫不費力地放棄它。