2012-03-28 91 views
5

我們有一個系統,客戶在先到先得的基礎上分配產品。針對一個數據庫表上大量請求的最佳解決方案

我們的產品表包含開始於零,我們用它來跟蹤有多少產品已分配即用戶保留一個產品,並得到分配1遞增的主鍵,接下來用戶將獲得2等

問題在於,潛在成千上萬的用戶會在任何給定的小時內訪問系統。所有的人都會打這張桌子。

由於我們需要確保每個客戶只分配一個產品並跟蹤有多少產品已分配,因此我們對每個訪問該系統的客戶使用一個行鎖,以確保他們在下一個客戶之前寫入表中擊中系統 - 即執行先來先服務的規則。

我們關注的是每個請求進入SQL Server 2008企業版和行鎖的處理時間的瓶頸。

因爲我們需要確保primay關鍵的完整性,因此任何需要複製行不通的,我們不能使用多臺服務器。

有誰知道有什麼好的解決方案,在處理上一個數據庫表的請求數量龐大的特別有效的?

多一點信息: 有問題的表基本上只包含兩個字段 - ID和客戶ID。解決方案是免費贈送一百萬件產品 - 因此對高需求的預期以及爲什麼使用增量主鑰匙作爲關鍵對我們有意義 - 一旦關鍵點擊數百萬,則不再有客戶可以註冊。而且,這些產品都是不同的,因此分配正確的密鑰是重要的,例如,前100名顧客進入receieve更高​​價值的產品比下100等

感謝您的幫助。

+1

能否請您重新標籤,包括[SQLSERVER]你能告訴我的版本及版本,如果您編輯您的問題,並告訴我們你有'SQL2008企業Edition'例如,我們也許能夠提供量身定做的解決方案如表分區可在SQL 2008 EE – 2012-03-28 03:16:18

+0

謝謝Jeremy。增加了額外的信息。 – 2012-03-28 03:22:03

+0

明顯的第一個問題;你是否剝奪了獲得密鑰的事務中的所有其他內容?例如。在嘗試獲得關鍵所需知道的一切之前,你知道嗎?去桌子上拿鑰匙,然後再做其他的事情? – Karl 2012-03-28 03:40:56

回答

5

首先,爲了消除密鑰生成的問題,我會提前生成它們。它只有100萬行,這意味着您不必擔心管理密鑰生成過程。這也意味着您不必擔心會意外地生成太多的行,因爲一旦填滿了表,您將只執行UPDATE,而不執行INSERT。

這裏的一個重要問題是,所有1m項目是否相同?如果他們是,那麼它是什麼順序的鑰匙(或者即使他們有一個訂單)無關緊要,因此,當客戶提交請求時,您只需'嘗試'更新表格,大致如下:

UPDATE TOP(1) dbo.Giveaway -- you can use OUTPUT to return the key value here 
SET CustomerID = @CurrentCustomerID 
WHERE CustomerID IS NULL 

IF @@ROWCOUNT = 0 -- no free items left 
PRINT 'Bad luck' 
ELSE 
PRINT 'Winner' 

另一方面,如果1米物品不同,那麼您需要另一種解決方案,例如第1項是X,第2-10項是Y,第11-50項是Z等。在這種情況下,按照提交請求的順序爲客戶分配密鑰很重要,因此您應該查看某種排隊系統,也許使用Service Broker。每個客戶向隊列添加一個請求,然後一個存儲過程一次處理一個請求,併爲它們分配最大空閒密鑰,然後返回他們贏得的細節。

+0

SQL 2008中不建議使用SET ROWCOUNT。使用'UPDATE TOP(1)'代替? http://msdn.microsoft.com/en-us/library/ms188774%28v=sql.100%29.aspx – 2012-03-28 07:21:39

+0

@EdHarper是的,這是一個很好的觀點,我已經更新了我的示例。雖然OP的關鍵信息當然是,只要您只更新一行,更新哪一行並不重要。 – Pondlife 2012-03-28 08:59:58

+0

感謝Pondlife。這些項目是不同的,所以聽起來像排隊是要走的路,只是接受在高峯時間處理每個請求會有一些延遲。 我在想的另一個解決方案是將所有的奇數放在一個數據庫中,甚至在另一個數據庫中放入一個負載均衡器,然後用一個簡單的位開關將交替的客戶發送給數據庫 - 對此作爲解決方案的任何想法?我猜我可能會將瓶頸轉移到負載平衡器上,而這可能最終需要一個隊列呢? 感謝您的幫助,非常感謝。 – 2012-03-28 13:33:08

相關問題