創建分區會減少鎖定,我們如何在 sql-server 中實現這一點?
客戶希望我們的應用程序能夠更快地處理更多數據,因此安排與他們的 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 和其他調整
- 將登台數據庫放在單獨的捲上。