7

Tôi có một vài bảng (User & UserRecord) trong cơ sở dữ liệu của mình bị phân mảnh (như 99%) và làm cho toàn bộ cơ sở dữ liệu và do đó trang web bị dừng lại.Vấn đề phân mảnh máy chủ SQL

UserRecord giống như ảnh chụp nhanh người dùng đó tại một thời điểm. Người dùng giống như bản ghi chính cho người dùng đó. Người dùng có từ 0 đến nhiều UserRecords. Người dùng có khoảng một triệu hàng, UserRecord có khoảng 2,5 triệu. Những bảng này được viết rất nhiều. Họ cũng đang được tìm kiếm rất nhiều. Cả hai đều sẽ lớn hơn rất nhiều. Các chỉ mục chính bị phân mảnh nặng là các khóa chính của bảng User và UserRecord.

DB là SQL Server 2012 và tôi đang sử dụng Khung thực thể và tôi không sử dụng bất kỳ quy trình được lưu trữ nào.

Bàn giống như thế này:

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 

(không chắc chắn nếu Danh sách này là quan trọng hay không nhưng nghĩ rằng tôi muốn đưa nó vì nó có liên quan đến User_Record Danh sách có từ 0 đến nhiều UserRecords.)

Chúng tôi đã thiết lập một kế hoạch bảo trì SQL để xây dựng lại các chỉ mục hàng ngày mà không giúp đỡ, nhưng đôi khi không đủ.

Một người bạn đã đề xuất chúng tôi sử dụng hai cơ sở dữ liệu, một để đọc, một để viết và chúng tôi đồng bộ hóa DB đọc từ DB viết. Không phải là tôi biết bất cứ điều gì về việc này, nhưng vấn đề đầu tiên tôi thấy với giải pháp này là chúng ta cần cập nhật dữ liệu khi xem trang web. Ví dụ: nếu chúng tôi cập nhật chi tiết người dùng hoặc UserRecord, chúng tôi muốn xem những thay đổi đó ngay lập tức.

Có ai có bất kỳ đề xuất nào về cách tôi có thể khắc phục sự cố này trước khi nó không thể kiểm soát được không?

+0

Định nghĩa bảng là gì? Bạn có sử dụng GUID làm khóa chính không? –

+0

Bạn có habe một chỉ số nhóm trên một cột uniqueidentifier? điều này thường leeds để phân mảnh sau khi một số chèn ... bởi vì các giá trị là ngẫu nhiên ... – PrfctByDsgn

+0

Tôi đã thêm một số chi tiết hơn cho câu hỏi – Owen

Trả lời

5

Chỉ mục được nhóm kiểm soát thứ tự dữ liệu trên DISK. Đây là một trong những lý do chính tại sao nó thường được khuyến cáo rằng bạn thiết lập một phím số nguyên luôn tăng để hoạt động như chỉ số nhóm. Bằng cách này khi có thêm dữ liệu được thêm vào bảng, chúng sẽ được thêm vào cuối dữ liệu hiện có.

Nếu đó không phải là số tự động và hàng mới có thể chứa giá trị được đặt ở đâu đó giữa các giá trị hiện tại, thì SQL Server về cơ bản sẽ đẩy dữ liệu lên đĩa nơi nó thuộc về (để giữ lại thứ tự của các giá trị khóa chỉ mục nhóm), sản xuất phân mảnh và chi phí có khả năng nghiêm trọng khi IO viết tiếp tục làm chậm cơ sở dữ liệu.

Tôi nghi ngờ bạn có cùng sự cố với giá trị UserRecord của mình.

Vì vậy, những gì tôi sẽ làm, là thêm một cụm riêng biệt autoincreasing khóa chính cho mỗi bảng và làm lại tài liệu tham khảo FK của bạn & truy vấn khi cần thiết.

+0

Tại sao không khai báo chỉ mục PK là không được nhóm? –

+0

Thông thường, tốt nhất nên có chỉ số nhóm trên bảng. Ngay cả khi bạn bỏ nó ra và tạo một PK không phân cụm, nó sẽ lưu trữ bảng như một HEAP có một số vấn đề khác. Ví dụ, tất cả các truy vấn đang chạy với nó trước tiên sẽ phải tìm kết quả chỉ mục nonclustered, sau đó tìm các hàng phù hợp từ HEAP để lấy các giá trị khác vì chúng không dễ dàng như chúng làm với chỉ số nhóm. Một lần nữa, tạo ra chi phí không cần thiết làm chậm DB. Google có một vài bài viết hay về các bảng HEAP vs CLUSTERED. – Kahn

+1

Cảm ơn, có vẻ như SQL Server cực kỳ khác với các DBMS khác (ví dụ: Postgres, Oracle) khi nói đến lập chỉ mục. –

Các vấn đề liên quan