7

我在我的數據庫中有幾個表(User & UserRecord),這些表得到極其分散的狀態(如99%),並導致整個數據庫因此導致網站崩潰。SQL Server碎片問題

UserRecord有點像用戶在某個時間點的快照。用戶就像該用戶的主記錄。用戶有0到多個UserRecords。用戶有大約一百萬行,UserRecord有大約250萬行。這些表格寫得很多。他們也被搜查了很多。他們都會變得更大。變得非常分散的主要索引是User和UserRecord表的主鍵。

該數據庫是SQL Server 2012年,我正在使用實體框架,我沒有使用任何存儲過程。

表是這個樣子:

USER 
UserName string PK ClusteredIndex 
FirstName string 
LastName string 
+SeveralMoreRows 

USER_RECORD 
UserRecordId int PK ClusteredIndex 
ListId int FK(List) 
UserName string FK(User) NonClusteredIndex 
Community string NonClusteredIndex 
DateCreated datetime 
+LotsMoreRows 

LIST 
ListId int PK & ClusteredIndex 
Name string 
DateCreated datetime 

(不知道名單,這是重要的或沒有,但想到我會包括它,因爲它是關係到User_Record列表中包含了0到許多UserRecords。)

我們已經設置了SQL維護計劃來每天重建索引,這有助於幫助,但有時還不夠。

一位朋友建議我們使用兩個數據庫,一個用於讀取,一個用於寫入,並且我們同步從寫入DB讀取的數據庫。並不是說我知道做這件事的任何事情,但我看到這個解決方案時遇到的第一個問題是我們在查看網站時需要最新的數據。例如,如果我們更新用戶詳細信息或UserRecord,我們希望立即看到這些更改。

有沒有人有任何建議,我可以解決這個問題之前,它螺旋失控?

+0

什麼是表格定義?你使用GUID作爲主鍵嗎? –

+0

你是否是唯一標識符列上的聚集索引?這往往會在一些插入後導致碎片...因爲這些值是隨機的... – PrfctByDsgn

+0

我在問題中添加了一些更多的細節 – Owen

回答

5

聚簇索引控制着磁盤上數據的順序。這是通常建議您設置一個始終增加的整數鍵以充當聚簇索引的主要原因之一。這樣,隨着更多數據添加到表中,它們將被添加到當前現有數據的末尾。

如果它不是一個自動增加的數字,並且新行可能包含將在現有值之間的某個位置進行排序的值,那麼SQL Server將基本上將數據推送到它所屬的磁盤上(以保留聚簇索引鍵值的順序),由於IO寫入進一步減慢了數據庫速度,因此產生碎片和潛在的嚴重開銷。

我懷疑你的UserRecord值有同樣的問題。

所以我要做的是爲每個表添加一個單獨的集羣自動增長主鍵,並在必要時重新修改您的FK引用&查詢。

+0

爲什麼不將PK索引聲明爲非集羣? –

+0

通常最好在表上有一個聚集索引。即使你將其忽略並創建一個非聚集PK,它也會將該表存儲爲一個HEAP,其中還有其他一些問題。例如,對它運行的所有查詢首先必須找到非聚簇索引匹配,然後從HEAP中查找匹配的行以獲取其他值,因爲它們不像聚簇索引那樣容易。再次,產生不必要的開銷減慢了數據庫。 Google在HEAP和CLUSTERED表格上有幾篇很好的文章。 – Kahn

+1

謝謝,聽起來像SQL Server與其他DBMS(例如Postgres,Oracle)在索引方面有很大的不同。 –