2010-05-27 26 views
6

Câu hỏi này là về những gì xảy ra với việc tổ chức lại dữ liệu trong chỉ mục nhóm khi chèn xong. Tôi giả định rằng sẽ tốn kém hơn khi thực hiện chèn trên một bảng có chỉ số nhóm hơn một không phải vì việc tổ chức lại dữ liệu trong một chỉ số nhóm liên quan đến việc thay đổi bố cục vật lý của dữ liệu trên đĩa. Tôi không chắc chắn làm thế nào để cụm từ câu hỏi của tôi ngoại trừ thông qua một ví dụ tôi đã đi qua tại nơi làm việc.Chỉ mục nhóm - đa phần so với chỉ mục một phần và ảnh hưởng của các lần chèn/xóa

Giả sử có một bảng (Junk) và có hai truy vấn được thực hiện trên bảng, truy vấn đầu tiên tìm kiếm theo Tên và truy vấn tìm kiếm thứ hai theo Tên và Thứ gì đó. Như tôi đang làm việc trên cơ sở dữ liệu tôi phát hiện ra rằng bảng đã được tạo ra với hai chỉ số, một để hỗ trợ mỗi truy vấn, như vậy:

--drop table Junk1 
CREATE TABLE Junk1 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name ON Junk1 
(
    Name 
) 

CREATE NONCLUSTERED INDEX IX_Name_Something ON Junk1 
(
    Name, Something 
) 

Bây giờ khi tôi nhìn vào hai chỉ số, có vẻ như là IX_Name dư thừa từ IX_Name_Something có thể được sử dụng bởi bất kỳ truy vấn nào muốn tìm kiếm theo Tên. Vì vậy, tôi sẽ loại bỏ IX_Name và làm IX_Name_Something các chỉ số nhóm thay vì:

--drop table Junk2 
CREATE TABLE Junk2 
(
    Name char(5), 
    Something char(5), 
    WhoCares int 
) 

CREATE CLUSTERED INDEX IX_Name_Something ON Junk2 
(
    Name, Something 
) 

Có người cho rằng chương trình lập chỉ mục đầu tiên nên được giữ vì nó sẽ cho kết quả chèn hiệu quả hơn/xóa (giả định rằng không có cần phải lo lắng về cập nhật cho Tên và Cái gì đó). Điều đó có hợp lý không? Tôi nghĩ phương pháp lập chỉ mục thứ hai sẽ tốt hơn vì nó có nghĩa là một chỉ số ít cần phải được duy trì.

Tôi sẽ đánh giá cao bất kỳ thông tin chi tiết nào về ví dụ cụ thể này hoặc chỉ cho tôi biết thêm thông tin về việc duy trì các chỉ mục nhóm.

Trả lời

9

Có, chèn vào giữa bảng hiện có (hoặc trang của nó) có thể tốn kém khi bạn có chỉ số nhóm nhỏ hơn tối ưu. Trường hợp xấu nhất sẽ là phân chia trang: một nửa số hàng trên trang sẽ phải được di chuyển ở nơi khác và chỉ mục (bao gồm các chỉ mục không nhóm trên bảng đó) cần phải được cập nhật.

Bạn có thể làm giảm bớt vấn đề đó bằng cách sử dụng quyền clustered index - một trong đó lý tưởng nhất là:

  • hẹp (chỉ có một trường duy nhất, càng nhỏ càng tốt)
  • tĩnh (không bao giờ thay đổi)
  • duy nhất (để Máy chủ SQL không cần phải thêm các bộ duy nhất 4 byte vào các hàng của bạn)
  • ngày càng tăng (chẳng hạn như INT INTENTITY)

Bạn muốn một khóa hẹp (lý tưởng là một INT) vì mỗi mục nhập trong mỗi và mọi chỉ mục không được nhóm lại cũng sẽ chứa (các) khóa phân cụm - bạn không muốn đặt nhiều cột trong khóa phân cụm của mình, bạn cũng không muốn đặt những thứ như VARCHAR (200) ở đó!

Với chỉ số nhóm ngày càng tăng, bạn sẽ không bao giờ thấy trường hợp phân tách trang. Sự phân mảnh duy nhất mà bạn có thể gặp phải là từ việc xóa ("pho mát thụy sĩ").

Kiểm tra bài viết Kimberly Tripp của excellet blog trên indexing - đáng chú ý nhất:

Giả sử có một bảng (Junk) và có hai truy vấn được thực hiện trên bảng, tìm kiếm truy vấn đầu tiên bởi Tên và các tìm kiếm truy vấn thứ hai bởi Tên và Một cái gì đó. Như tôi đang làm việc trên cơ sở dữ liệu tôi phát hiện ra rằng bảng đã được tạo ra với hai chỉ số, một để hỗ trợ mỗi truy vấn, như vậy:

Đó chắc chắn là không cần thiết - nếu bạn có một chỉ mục trên (Name, Something), chỉ mục đó cũng có thể được sử dụng nếu bạn tìm kiếm và hạn chế chỉ WHERE Name = abc - có chỉ mục riêng chỉ với cột Name là hoàn toàn không cần thiết và chỉ lãng phí dung lượng (và tiết kiệm thời gian được cập nhật). Vì vậy, về cơ bản, bạn chỉ cần một chỉ số duy nhất trên (Name, Something) và tôi đồng ý với bạn - nếu bạn không có chỉ mục nào khác trên bảng này, thì bạn sẽ có thể thực hiện điều này cho khóa được nhóm. Vì chìa khóa đó sẽ không bao giờ tăng và cũng có thể thay đổi (phải không?), Đây có thể không phải là một ý tưởng tuyệt vời.

Các tùy chọn khác sẽ được giới thiệu một đại diện ID INT IDENTITY và cụm trên đó - với hai lợi ích:

  • đó là tất cả một phím clustered tốt thì có thể, bao gồm ngày càng tăng -> bạn sẽ không bao giờ có bất kỳ vấn đề với chia tách trang và hiệu suất cho các hoạt động INSERT
  • bạn vẫn nhận được tất cả những lợi ích của việc có một chìa khóa phân nhóm (xem bài đăng trên blog Kim Tripps' - bảng nhóm là hầu như luôn luôn thích hợp hơn để đống)
+1

Đẹp, giải thích kỹ lưỡng. –

0

Ai đó đã đề xuất rằng lược đồ lập chỉ mục đầu tiên nên được lưu giữ vì nó sẽ dẫn đến việc chèn/xóa hiệu quả hơn

Đó là một yêu cầu không có thật. Dữ liệu đặt hàng được đặt hàng dữ liệu và cùng một IO sẽ được thực hiện.

SET STATISTICS IO ON 
-- your insert statement here 
0

Bạn có thể tạo một nhóm chỉ số duy nhất trên một cột, không phải là hai hoặc nhiều hơn như vậy chọn cột mà ứng dụng của bạn sẽ chủ yếu được truy vấn trên, giống như truy vấn wildcard trên fullnames khách hàng, vv (xem discussion)

+0

Đó là sai, vui lòng đọc: http://msdn.microsoft.com/en-us/library/aa933131 (SQL.80).aspx "một bảng có thể chứa chỉ một chỉ mục nhóm. Tuy nhiên, chỉ mục có thể bao gồm nhiều cột " – Anssssss

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