Các trường INCLUDE chỉ mục lớn sẽ ảnh hưởng đến hiệu năng hệ thống như thế nào?


15

Câu hỏi này là về chỉ số hiệu suất SQL Server với một varchar(2000)là một INCLUDEtrong một chỉ số bao phủ.

Tôi đang cố gắng cải thiện hiệu suất trong một ứng dụng cơ sở dữ liệu chậm và không ổn định. Trong một số trường hợp, dữ liệu được truy cập thông qua chuỗi varchar lớn, với các truy vấn bao gồm các hoạt động chuỗi multple như SUBSTRING(), SPACE(), và DATALENGTH(). Đây là một ví dụ đơn giản về truy cập;

update fattable set col3 =  
   SUBSTRING(col3,1,10) + '*' + 
   SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2

Lược đồ trông như thế này:

CREATE TABLE [dbo].[FatTable]( 
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [col1] [nchar](12) NOT NULL, 
    [col2] [int] NOT NULL, 
    [col3] [varchar](2000) NOT NULL, ... 

Chỉ mục sau đây đã được xác định, với trường bao phủ trên cột văn bản lớn.

CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable]  ( [col2] ASC ) 
    INCLUDE( [col3] )

Từ những gì tôi đã đọc, BAD sẽ đưa các trường dữ liệu lớn vào một chỉ mục. Tôi đã đọc một số bài viết, bao gồm http://msdn.microsoft.com/en-us/l Library / ms190806.aspx trong đó thảo luận về tác động của phân trang và kích thước đĩa đến hiệu suất chỉ mục. Điều này đang được nói, kế hoạch truy vấn chắc chắn sử dụng chỉ số bao phủ. Tôi không có đủ thông tin để xác định điều này thực sự gây tốn kém cho tôi về mặt tải hệ thống. Tôi biết rằng về tổng thể, hệ thống đang hoạt động kém và tôi lo ngại rằng đây là một trong những vấn đề. Câu hỏi:

  • Là đặt varchar(2000)cột này trong chỉ mục INCLUDEbao giờ là một ý tưởng tốt?

  • Vì các INCLUDEtrường được lưu trữ trong các nút lá, chúng có hiệu suất chỉ số tác động nhiều không?

Cập nhật: Cảm ơn bạn đã trả lời tuyệt vời! Đây là một câu hỏi không công bằng theo một số cách - như các bạn nói, không có câu trả lời đúng tuyệt đối nếu không có số liệu thống kê và hồ sơ thực tế. Giống như rất nhiều vấn đề hiệu suất, tôi đoán câu trả lời là "nó phụ thuộc".


Giá trị thực tế là bao lâu? Một VARCHAR(2000)thứ thường lưu trữ chỉ mười ký tự là một điều; 2.000 byte cho mỗi bản ghi là một cái gì đó khác.
Jon của tất cả các giao dịch

Chỉ là một quan sát: Một cái gì đó "có mùi" ở đây là cột lớn có thể chứa 1) văn bản miễn phí, trong trường hợp đó các truy vấn có thể được lợi từ việc viết lại để sử dụng chỉ mục FULLTEXT hoặc 2) dữ liệu được mã hóa "có thể đọc được" của con người (ví dụ: thông minh rộng các khóa, như số VIN) có thể được lợi từ việc chia thành các cột riêng biệt hoặc các cột được tính toán bền vững với INDEX. Nói cách khác, dòng thông tin và thay đổi dữ liệu không được thiết kế tốt.
Graeme

1
Có #Graeme, có một mùi hôi ở đây - tôi nghĩ nó được gọi là "di sản". Có vô số vấn đề trong cơ sở dữ liệu này.
RaoulRubin

Câu trả lời:


14

Bao giờ là một từ lớn, nhưng, nói chung, không, tôi sẽ không đặt một trường varchar (2000) vào INCLUDE.

Và vâng, cách dữ liệu được lưu trữ ở cấp độ trang có thể ảnh hưởng nghiêm trọng đến hiệu suất của chỉ mục, tùy thuộc vào cách sử dụng chỉ mục.

Vấn đề là, càng nhiều hàng dữ liệu bạn có thể nhồi nhét vào một trang, thì càng ít trang phải truy cập, phần lớn hệ thống của bạn càng nhanh. Thêm một cột thực sự lớn có nghĩa là ít thông tin được lưu trữ trên một trang, do đó, trong trường hợp tìm kiếm hoặc quét phạm vi, nhiều trang phải được đọc để truy xuất dữ liệu, làm chậm nghiêm trọng công cụ.

Để biết chắc chắn liệu đây có phải là vấn đề đối với truy vấn của bạn hoặc trên hệ thống của bạn, bạn phải theo dõi số lần đọc, đặc biệt là số trang mà truy vấn sử dụng.


Cảm ơn Grant. Như tôi đã đề cập một nhận xét khác, thông tin hiệu suất tốt là khan hiếm, do đó câu hỏi trừu tượng. Tôi không có kinh nghiệm theo dõi chi phí hiệu suất kích thước trang. Linh cảm của tôi là nó là một vấn đề, sẽ xem liệu tôi có thể có được một số thống kê.
RaoulRubin

1
thiết lập thống kê IO trên cho truy vấn sẽ cho bạn biết rất nhiều, số lần đọc logic thể hiện số lượng trang được truy cập. Bạn cũng có thể theo dõi giây / đọc từ quầy perfmon để có được thông tin hiệu suất chung.
Grant Fritchey

6

Bạn có thể xem lại khóa chỉ mục được phân cụm hiện tại và có thể tạo col2khóa chỉ mục được phân cụm thay thế không? Bằng cách này, bạn có được hành vi 'bao gồm' (vì các chỉ số được nhóm luôn luôn 'bao gồm' mọi thứ) sẽ không sao chép dữ liệu. Điều này, tất nhiên, là đối tượng của nhiều ifbut, dù sao có lẽ là đáng xem xét. Tất nhiên, nếu chỉ mục cụm hiện tại đang thực thi một ràng buộc (khóa chính, duy nhất) cho biết ràng buộc sẽ phải được chuyển sang một chỉ mục không được phân cụm.


Đề xuất của bạn về PK là một ý tưởng tuyệt vời, mặc dù tôi sẽ không thể áp dụng nó trong trường hợp này - PK hiện tại là cần thiết cho các truy vấn khác. (Đây là một kỹ thuật tôi sẽ giữ trong hộp công cụ!)
RaoulRubin

4

Thật khó để trả lời. Tất cả sẽ phụ thuộc vào tỷ lệ đọc: ghi của bạn. Bạn đã kiểm tra khối lượng công việc hoặc mô phỏng toàn bộ chu trình kinh doanh trên hệ thống kiểm tra, có và không có cột bao gồm chưa? Việc tra cứu mà không có nó có thể tốn rất nhiều chi phí, nhưng nếu bạn cập nhật dữ liệu thường xuyên hơn bạn đang đọc nó, điều đó có thể ổn.


Tổng thể đọc so với cập nhật chủ yếu là cân bằng. Các vấn đề về tổ chức và quyền riêng tư làm cho khó có được số liệu thống kê hữu ích và các bài kiểm tra thực tế. Vì chúng ta đang bay gần như mù, chúng ta phải nhìn mọi thứ từ một quan điểm trừu tượng (do đó câu hỏi này). Thử nghiệm sẽ có nghĩa là đẩy các thay đổi vào sản xuất và quan sát kết quả - rất rủi ro.
RaoulRubin

2
Và có phải hầu hết các lần đọc thực sự kéo VARCHAR(2000)cột này hay bạn đang khắc phục sự cố hiệu năng của một truy vấn rất cụ thể không đại diện cho hầu hết các truy vấn? Như Grant gợi ý nếu cột này không được sử dụng trong nhiều truy vấn hoặc thực sự gây ra sự cố cho tìm kiếm, có lẽ sẽ tốt hơn khi trả giá cho việc tra cứu khi bạn cần, nhưng không trả tiền cho bộ lưu trữ khi bạn không . Một lần nữa, thật khó để nói bạn nên ở phía nào của hàng rào, vì chúng tôi không thực sự có bất kỳ chi tiết cụ thể nào (và thậm chí khó hơn vì bạn không thể kiểm tra - bạn nên cố gắng khắc phục điều đó).
Aaron Bertrand

3

Tôi biết tôi đến trễ bữa tiệc này, nhưng tôi sẽ lập chỉ mục chính xác các biểu thức được sử dụng để định vị các hàng, chẳng hạn như chuỗi con (col3,10,1). Nếu toàn bộ col3 đã từng được sử dụng, tôi sẽ lập chỉ mục CHECKSUM (col3) (hiểu rằng tất nhiên có thể có va chạm).

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.