RID vs INCLUDE trên một lĩnh vực rộng lớn


7

Tôi có một bảng lưu trữ ghi chú

create tblNote(  
  Id int identity(1,1),  
  ParentId  int ,   
  ParentType varchar(32),   
  NoteType varchar(32),   
  Note varchar(max),  
  CreatedBy varchar(25),   
  CreatedDate  datetime,   
  .  
  .  
  .  
  <other metadata about the note>  
)  

Gần đây tôi đã đọc rất nhiều về cách MSSS xử lý các chỉ mục (2005 và chuyển tiếp).

Tôi có một chỉ mục nhóm trên ID

[Tôi đã cân nhắc việc thay đổi chỉ mục được nhóm thành ParentId, ParentType vì điều đó khá hẹp và nó là tĩnh. ]

Tỷ lệ truy vấn áp đảo đối với bảng này sẽ nằm dọc theo dòng

select NOTE, createdDate, createdBy 
from tblNote 
where parentId = 12 and parentType = 'RFQ'

Câu hỏi tôi muốn hỏi hôm nay (mặc dù mọi phản hồi đều được chào đón) là đây:

Chỉ số NC tôi có thể thêm là:

create index  idx_nc_note_parent(  
        parentId ,   
        parenttype  
    )  
    include (createdby, createdDate)  

Điều này sẽ hữu ích trong việc tạo danh sách nhỏ các ghi chú nơi chúng tôi có thể bao gồm ai và khi nhập thông tin.

Tôi do dự bao gồm một varchar(max)lĩnh vực. Có vẻ như nó thực sự sẽ làm tổn thương số lượng chỉ mục sẽ được lưu trữ (Điều này hợp lý hay không hợp lý)

Giả sử tôi không bao gồm NOTEtrường, Tra cứu RID sẽ cần thiết để thực sự tìm nạp nội dung ghi chú nếu được yêu cầu.

Mặc dù tôi đã đọc khá nhiều về việc tra cứu RID đắt tiền như thế nào, nhưng vẫn phải tốt hơn để có chỉ số này chứ không phải là quét bảng, ĐÚNG?

[xin lỗi về khối mã, tôi đã thêm 4 khoảng trắng, nhưng có lẽ tôi đã làm sai? ]


Bạn có bao nhiêu ParentTypes khác nhau? Nếu chúng không nằm trong hàng tỷ, cột đó có thể được thu hẹp hơn nhiều.
ypercubeᵀᴹ

ParentType có thể dễ dàng thu nhỏ xuống còn 10 ký tự, nhưng tôi không nghĩ điều đó thực sự ảnh hưởng đến câu hỏi. Quan điểm của bạn là gì?
greg

Có bao nhiêu hàng bạn mong đợi để lấy lại cho một (parentId, parentType)kết hợp trung bình ?
Jon Seigel

Nó thường là một số nhỏ. <10. Một ví dụ tuyệt vời của bảng này là những bình luận chúng ta đang sử dụng.
greg

1
Tôi nghĩ bạn có nghĩa là tra cứu chính, không phải tra cứu RID. Tra cứu RID xảy ra trên đống, chính xác là do không có chỉ mục được nhóm (và không có chỉ mục hợp lệ thỏa mãn truy vấn).
Aaron Bertrand

Câu trả lời:


5

Vì bạn đã nói rằng hầu hết các truy vấn thường trả về một vài hàng, cho phép truy vấn sử dụng tra cứu RID (tra cứu khóa trong trường hợp này vì bảng có chỉ mục được nhóm) là hoàn toàn tốt để truy xuất trường lớn. Đối với một hệ thống có tính sẵn sàng cao, tôi không thể khuyên bạn nên đặt loại LOB trong một chỉ mục vì điều này ngăn việc xây dựng lại trực tuyến (đối với các phiên bản SQL Server trước năm 2012). Ngoài ra, bạn cần phải rất cẩn thận rằng kế hoạch truy vấn luôn bám sát kế hoạch loại tìm kiếm và không đưa vào quét bảng có thể rất tốn kém. Đây là trường hợp tôi có thể sử dụng gợi ý bảng (hoặc hướng dẫn kế hoạch nếu truy vấn không thể sửa đổi) ngay cả khi không thực sự cần thiết.

Một tùy chọn khác là tạo lại chỉ mục được nhóm trên sự kết hợp parentIdparentTypenếu sự kết hợp các giá trị này là tĩnh và thường tăng theo thời gian. Tuy nhiên, sẽ tốt hơn nếu parentTypelà một loại tích phân, và bạn có thể muốn xem xét thay đổi điều đó bằng mọi cách để tiết kiệm không gian lưu trữ nếu bảng cơ sở đang hoặc sẽ trở nên lớn. Xem xét sự thay đổi này cũng liên quan đến việc xem xét nó có thể ảnh hưởng đến việc lập chỉ mục cho các lớp truy vấn khác chạy trên bảng này như thế nào.

Nếu một trong hai phương pháp đó không đủ nhanh cho khối lượng công việc, hãy xem xét triển khai giải pháp lưu trữ dữ liệu bằng cách sử dụng một cái gì đó như AppFoven, quy mô dễ dàng hơn nhiều so với chạy truy vấn SQL mỗi khi bạn cần dữ liệu. Đây có thể là một khoản tiền rất lớn; chi phí được thêm vào phức tạp.


Kể từ SQL-Server 2012, việc xây dựng lại TRỰC TUYẾN hiện được hỗ trợ cho VARCHAR (MAX), NVARCHAR (MAX), VARBINARY (MAX) và XML.
Calgary

Cảm ơn vì đã góp ý. ParentId, ParentType, SEQ là tĩnh nhưng không bao giờ tăng.
greg

1

Bạn có thể thử cái này không?

Tạo một chỉ mục trên ParentID và ParentType để tra cứu ID hiện hành ...

Create  NonClustered Index idx_nc_note_parent On tblNote (parentID, parentType)

Tham gia ID trở lại bảng cơ sở để lấy thông tin mong muốn bằng cách sử dụng chỉ mục được nhóm ...

Select  NOTE, createdDate, createdBy
From   (Select  ID
        From    tblNote
        Where   parentID = 12
        And     parentType = 'RFQ') n
Join    tblNote tn
        On  n.ID = tn.ID

Tôi sẽ thử điều đó và xem những gì kế hoạch truy vấn làm. Càng nghĩ về điều này, tôi càng nghĩ rằng có lẽ tôi nên thay đổi Chỉ số cụm thành ParentId, ParentType, NoteId. (Thêm NoteId sẽ đảm bảo tính duy nhất)
greg

@greg Đó sẽ là một ý tưởng thực sự tồi tệ. Nếu bạn có một cột danh tính, tôi không thể nghĩ đến bất kỳ kịch bản nào mà bạn không muốn sử dụng nó làm chỉ mục được nhóm của bạn. Nếu bạn sử dụng ParentID, bạn sẽ tự mở tất cả các vấn đề phân mảnh khủng khiếp trừ khi bạn chèn tuần tự cha mẹ. Nếu đó là dữ liệu không thay đổi tĩnh thì tôi cho rằng nó cũng tốt. Nếu bạn làm điều này và bạn thường xuyên chèn vào bảng, hãy cân nhắc sử dụng fillfactor thấp hơn 100 để chừa chỗ cho các phần chèn mới.
Eric J. Giá

1
Câu trả lời này cho thấy rằng sử dụng phép nối sẽ nhanh hơn tra cứu khóa / đánh dấu? Có thật không?
Jon Seigel

@ Love2Learn - Tôi nghĩ bạn đúng. Các bảng cha khác nhau sẽ có #s hàng khác nhau và do đó Id cha sẽ không luôn luôn tăng. Nó sẽ yêu cầu bảo trì vì sự phân mảnh sẽ được thiết lập. Cảm ơn vì đã giúp tôi nghĩ điều này thông qua. Theo đề xuất ban đầu của bạn để sử dụng một tham gia ... đây là một ý tưởng thú vị và tôi đã suy nghĩ khá nhiều. Kết luận tôi đưa ra là điều này có thể không đau, nhưng có lẽ nó sẽ không giúp ích gì. Các cấp độ lá của chỉ số NC đã bao gồm một khóa vào chỉ mục được nhóm. Đó thực chất là Tra cứu RID, nếu tôi hiểu mọi thứ.
greg

Cám ơn vì tất cả đóng góp. Tôi đã hy vọng thiết lập một thử nghiệm và chạy nó vào cuối tuần nhưng không thể làm cho thời gian có sẵn.
greg
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.