Sql-Server

創建分區會減少鎖定,我們如何在 sql-server 中實現這一點?

  • September 1, 2011

客戶希望我們的應用程序能夠更快地處理更多數據,因此安排與他們的 dba 會面討論選項。

此應用程序會生成大量用於報告的數據。在每次執行之前,刪除該項目的舊數據,執行計算,然後插入新數據。在繁忙時期,使用者會排隊數百個這樣的生成任務,我們同時執行多達 30 個。每次執行可能會創建 60K 行。

dba 建議我們可以將應用程序更改為使用 30 個分區(例如,每個執行緒一個)以減少插入和刪除期間執行緒之間的鎖定。他們建議在標準sql中我們可以做類似的事情

INSERT INTO schema.table.partition (...) VALUES (...)

我在msdn 文件中看不到這種語法,這意味著更改此應用程序很痛苦,但是否有可能做到這一點?據我了解,我們會改為使用分區函式根據表的列進行分區?

我已閱讀創建分區函式文件,但不完全確定如何創建函式以滿足我們的需求。更糟糕的是,我還沒有企業版來嘗試這個,所以我對不正確的語法表示歉意。

我在想,例如,如果我們有一個 items 表和一個 itemdata 表,其中包含該項目的數據,我們可能會通過基於類似itemid mod 30. 這會將項目 1 放在分區 1 中,將項目 2 放在分區 2 中,等等。我不確定我們是否可以在分區函式、方案、表聲明中執行此操作,或者我們是否需要創建一個計算列並使用價值觀條款?也不確定我們是否會看到任何性能改進?

這就是我認為我們可以實現的方式:

CREATE PARTITION FUNCTION SplittingItemIds_PFunc(decimal(18,0)) AS
RANGE LEFT FOR VALUES
(0,1,2,3, ... ,29)

CREATE PARTITION SCHEME SplittingItemIds_Scheme 
AS PARTITION SplittingItemIds_PFunc
ALL TO ([PRIMARY]);

CREATE TABLE ItemData  
(
   Id decimal(18,0),
   ItemId decimal(18,0),
   ...
)
ON PartitionSplittingItemIds_Scheme(ItemId % 30)

CREATE INDEX ItemData_ItemId_Idx ON ItemData(ItemId);

這種做法對嗎?根據我的閱讀,索引將自動分區 - 對嗎?

聽起來 dba 是在談論水平分區而不是表分區,通過使用規則打破麻煩的表,例如所有以字母 a 開頭的客戶在 tableA 中進入,b 在 tableB 中等等。這在某些情況下可能會有所幫助,並且可以使用任何版本的 SQL Server 完成,但有許多已經提到的相同問題,即 I/O。

如果底層 IO/磁碟對您不透明,則軟體無法解決此問題。

  • 如果添加分區,則不會產生 30 個執行緒
  • 如果您的所有分區都在同一個卷上,您將降低吞吐量

我曾在我們擁有的類似系統上工作過

  • 暫存數據庫
  • 暫存時的簡單恢復
  • 超時的延遲刪除(例如,新的或更新的執行是 INSERT)
  • 每次執行都有一個標題行來跟踪此狀態
  • 客戶端準備好時刷新到真實數據庫

我們也

  • 刪除了主表的 FK 和其他調整
  • 將登台數據庫放在單獨的捲上。

引用自:https://dba.stackexchange.com/questions/5295