10

Thông thường chỉ mục nhóm được tạo trong SQL Server Management Studio bằng cách đặt khóa chính, tuy nhiên câu hỏi gần đây của tôi về PK < -> chỉ mục nhóm (Meaning of Primary Key to Microsoft SQL Server 2008) đã chỉ ra rằng không cần thiết đặt chỉ mục PK và nhóm.Làm thế nào để chọn chỉ số nhóm trong SQL Server?

Vậy chúng ta nên chọn các chỉ mục nhóm sau đó như thế nào? Chúng ta hãy có ví dụ sau:

tạo bảng Customers (ID int, ...) tạo Orders bảng (ID int, CustomerID int)

Chúng tôi thường sẽ tạo ra PK/CI trên cả hai cột ID nhưng tôi nghĩ về việc tạo ra nó cho các Đơn đặt hàng trong CustomerID. Đó có phải là lựa chọn tốt nhất không?

+0

Bản sao có thể có của [SQL Server - Khi nào sử dụng Chỉ mục nhóm và không được nhóm?] (Https://stackoverflow.com/questions/18304376/sql-server-when-to-use-clustered-vs-non- clustered-index) –

Trả lời

11

Theo The Queen Of Indexing - Kimberly Tripp - những gì cô ấy sẽ xem xét trong một nhóm chỉ số chủ yếu là:

  • Unique
  • thu hẹp
  • tĩnh

Và nếu bạn cũng có thể đảm bảo:

  • Mẫu bao giờ tăng

thì bạn khá gần có khóa phân cụm lý tưởng!

Kiểm tra toàn bộ số blog post here của cô ấy và một điều thú vị khác về phân cụm các tác động chính đến hoạt động của bảng tại đây: The Clustered Index Debate Continues.

Bất kỳ thứ gì giống như INT (đặc biệt là INT INTENTENT) hoặc có thể là INT và DATETIME là các candiates lý tưởng. Vì những lý do khác, GUID không phải là ứng cử viên giỏi - vì vậy bạn có thể có GUID làm PK của bạn, nhưng đừng phân cụm bảng của bạn - nó sẽ bị phân mảnh ngoài sự công nhận và hiệu suất sẽ bị ảnh hưởng.

+0

Các bài đăng trên blog này vẫn có liên quan đến các phiên bản mới hơn của SQL Server hay các chỉnh sửa hiệu suất gần đây trong SQL Server 2008 và sau đó đã thay đổi các phương pháp hay nhất bằng cách nào đó? –

+0

@AdrianGrigore: mọi thứ vẫn hợp lệ, miễn là bạn sử dụng các bảng "bình thường" (ví dụ: không phải công cụ datawarehouse/columnstore) –

+0

Tuyệt vời, cảm ơn! :) –

1

Nếu bạn quan tâm đến việc phân cụm, thường là để giúp cải thiện việc truy xuất dữ liệu. Trong ví dụ của bạn, có thể bạn sẽ muốn tất cả các bản ghi cho một khách hàng nhất định cùng một lúc. Việc nhóm trên customerID sẽ giữ các hàng đó trên cùng một trang vật lý thay vì nằm rải rác trên nhiều trang trong tệp của bạn.

ROT: Cụm từ trên những gì bạn muốn hiển thị bộ sưu tập. Chi tiết đơn hàng trong đơn đặt hàng là ví dụ cổ điển.

+0

Chi tiết đơn hàng trên PO có thể là ý tưởng hay cho một cụm, nhưng không phải là chỉ có 2 hoặc 3 (hoặc một tá) mục hàng theo thứ tự điển hình. Trừ khi các hàng bạn đang nhóm lại với nhau bắt đầu để có được vào hàng chục hoặc hàng trăm, sau đó nó tốt hơn chỉ để cho SQL Server thực hiện tra cứu bookmark. tôi đã có một hệ thống yêu cầu kinh doanh phải tìm tất cả các "chi tiết đơn hàng" đã xảy ra trong quá trình chuyển đổi của một nhân viên thu ngân cụ thể (để xem họ có cân bằng) hay không. Không chuẩn hóa "mục hàng" với 'id' nếu ** Shift **, và sau đó nhóm trên ** Shift ** là một tốc độ tăng rất lớn. –

6

Ứng cử viên tốt nhất cho chỉ mục CLUSTERED là chìa khóa bạn sử dụng để tham khảo hồ sơ của mình thường xuyên nhất.

Thông thường, đây là số PRIMARY KEY, vì đó là nội dung được sử dụng trong các tìm kiếm và/hoặc mối quan hệ FOREIGN KEY.

Trong trường hợp của bạn, Orders.ID rất có thể sẽ tham gia vào các tìm kiếm và tham chiếu, vì vậy đây là ứng cử viên tốt nhất để trở thành cụm từ nhóm.

Nếu bạn tạo chỉ mục CLUSTERED trên Orders.CustomerID, những điều sau đây sẽ xảy ra:

  1. CustomerID không phải là độc đáo. Để đảm bảo tính duy nhất, một cột 32-bit ẩn đặc biệt được gọi là uniquifier sẽ được thêm vào mỗi bản ghi.

  2. Các bản ghi trong bảng sẽ được lưu trữ theo cặp cột này (CustomerID, uniquifier).

  3. Chỉ số phụ trên Order.ID sẽ được tạo, với (CustomerID, uniquifier) làm con trỏ ghi.

  4. Queries như thế này:

    SELECT * 
    FROM Orders 
    WHERE ID = 1234567 
    

    sẽ phải làm phẫu thuật bên ngoài, một Clustered Seek, vì không phải tất cả các cột được lưu trữ trong chỉ mục trên ID. Để truy xuất tất cả các cột, bản ghi đầu tiên phải được đặt trong bảng được nhóm.

hoạt động bổ sung này đòi hỏi IndexDepth càng nhiều trang đọc như một đơn giản Clustered Seek, các IndexDepth beign O(log(n)) tổng số các bản ghi trong bảng của bạn.

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