2012-11-30 202 views
0

我有一個數據庫表,UserRewards擁有三千萬以上的行。在這一行中,每行都有一個用戶ID和一個獎勵ID(以及其他字段)。將多行轉換爲單列

有一個用戶表(具有約400萬獨立用戶),具有主鍵的用戶ID等領域。 由於性能方面的原因,我希望將userrewards中每個用戶的獎勵ID移動到用戶的連接字段中。 (新的nvarchar(4000)字段稱爲獎勵) 我需要一個腳本,可以儘快做到這一點。

我用下面的腳本加入了獎勵光標,但它只有大約每分鐘100個用戶,這將需要時間太長得到儘管約400萬獨立用戶我處理。

set @rewards = (select REPLACE((SELECT rewardsId AS [data()] from userrewards 
where UsersID = @users_Id and BatchId = @batchId 
     FOR XML PATH('') ), ' ', ',')) 

任何建議,以優化?我即將嘗試一段時間循環,看看它是如何工作的,但任何其他想法都會被大大接受。

編輯:

我的網站具有以下功能:

我們有大約400萬用戶誰已預先分配5-10「大獎」。這種關係在用戶對話表中。

的用戶來到現場,我們確定他們,查找在數據庫中分配給他們的獎勵。

的問題是,該網站是非常受歡迎的,所以我有大量的人訪問該網站,同時請求他們的數據。以上將減少我的加入,但我知道這可能不是最好的解決方案。我的數據庫服務器在我調整網站的10秒內達到100%的CPU使用率,所以大多數人的請求超時(它們顯示爲錯誤頁面),或者他們得到結果,但不是在令人滿意的時間。

有人能夠提出一個更好的解決我的問題?

+0

...真的嗎?我已經可以告訴你,在SQL中使用分隔列(多值列)是**真的**嚴重不滿。 「對於性能」並不是一個令人信服的理由(查詢該列往往比其值得的更麻煩) - 通常它們最終分列在分析數據庫的不同列中。 4mil排馬馬虎虎,但花生在任何專用系統上。另外,遊標/循環在SQL中通常是錯誤的(通常這可能是性能問題的最大部分)。你想要解決什麼_actual_問題。還有哪些其他查詢「很慢」? –

+0

查詢速度很快,但我有5k-10k用戶同時點擊我的服務器,請求來自userrewards表的數據。 (擁有3000萬行的那個)。這將加入到用戶表和文件管理器上,並由用戶提供唯一標識符。我在一列中更新的代碼實現了更好的緩存,並且不會進行任何連接,速度也會提高很多。我只需要儘可能快地將我當前的大數據集轉換爲正確的格式。現在,SQL服務器是一個專用的盒子。我需要看到關於ugradding它..我應該RAM,CPU或兩者?目前8GB的內存,2.00 zeon CPU – mp3duck

+0

就單列的東西而言,雖然它可能會皺眉,但我有效的代碼比以前更快。 – mp3duck

回答

1

爲什麼我認爲你嘗試的方法是一個壞主意有幾個原因。首先,你將如何維護用戶表中的逗號分隔列表?有可能獎勵是在晚上批量加載的,所以現在這不是一個真正的問題。即便如此,有一天你可能想要更頻繁地分配獎勵。

其次,當你想刪除的獎勵或更改其中一方的名字,會發生什麼?您需要更新兩個不同位置的信息,而不是更新一個表格。

如果您擁有400萬用戶,並有數千個併發訪問,那麼由於計時造成的小的不一致性將會很明顯,並可能引發用戶投訴。 CEO抱怨爲什麼抱怨增加可能不是你想要處理的事情。

另一種方法是在UserRewards上創建索引(UserId,BatchId,RewardsId)。據推測,每個字段只有幾個字節,因此3000萬條記錄應該很容易適應8GB的內存(確保SQL Server幾乎分配了所有的內存!)。您需要的查詢可以通過此索引嚴格滿足,而無需將UserRewards錶帶入內存。所以,只有索引需要被緩存。而且,它將針對此查詢進行優化。

可能會減慢一切的一件事是分配獎勵的頻率。如果這些分配的讀取速率達到讀取速率的10%,則可能會有插入/更新阻塞讀取。你想用READ_NOLOCK來完成查詢,以避免這個問題。您還需要確保在記錄或頁面級別發生鎖定,以避免與讀取衝突。

+0

獎勵按月分配,並且在月內不會更改。網站在獎勵重新加載期間「關閉」。我已經在表格上有一個索引,但是我正在加入其他表格以獲取實際數據。但是,我可以在Web服務器上緩存「獎勵數據」,因爲這一次在本月不會改變。作爲索引,我應該包括主鍵在userrewads表上,或者只是外鍵(rewardsIDm usersID和batchID) – mp3duck

+0

我也使用uniqueidentifiers作爲我的鍵..這是否會導致我的問題,也許呢?我想我會看看我能否獲得另一個8GB內存的服務器 – mp3duck

0

也許爲時已晚,但使用uniqueidentifiers作爲關鍵字不僅會使您的存儲空間翻兩番(與使用ints作爲關鍵字相比),還會使查詢速度減慢數量級。避免!!!