Trước đây tôi đã viết về những lợi ích của việc sử dụng NOEXPAND
gợi ý, ngay cả trong Phiên bản Doanh nghiệp. Tất cả các chi tiết đều có trong bài viết được liên kết, nhưng để tóm tắt ngắn gọn:
- SQL Server sẽ chỉ tự động tạo thống kê về chế độ xem được lập chỉ mục khi
NOEXPAND
gợi ý bảng được sử dụng. Bỏ qua gợi ý này có thể dẫn đến cảnh báo kế hoạch thực thi về việc thiếu thống kê mà không thể giải quyết bằng cách tạo thống kê theo cách thủ công. - Máy chủ SQL sẽ chỉ sử dụng thống kê chế độ xem được tạo tự động hoặc thủ công trong các tính toán ước tính số lượng khi truy vấn tham chiếu trực tiếp đến chế độ xem và
NOEXPAND
gợi ý được sử dụng. Đối với tất cả, trừ các định nghĩa chế độ xem tầm thường nhất, điều này có nghĩa là chất lượng của các ước tính bản số có thể sẽ thấp hơn khi gợi ý này không được sử dụng, thường dẫn đến các kế hoạch thực thi kém tối ưu hơn. - Việc thiếu hoặc không thể sử dụng số liệu thống kê xem có thể khiến trình tối ưu hóa đoán theo ước tính cơ bản, ngay cả khi thống kê bảng cơ sở có sẵn. Điều này có thể xảy ra khi một phần của kế hoạch truy vấn được thay thế bằng một tham chiếu chế độ xem được lập chỉ mục bằng tính năng đối sánh chế độ xem tự động, nhưng thống kê chế độ xem không có sẵn, như đã mô tả ở trên.
Một hậu quả khác của việc không sử dụng NOEXPAND
gợi ý, mà tôi đã đề cập đến cách đây vài năm trong bài viết của mình, Giới hạn của Trình tối ưu hóa với Chỉ mục được Lọc:
NOEXPAND
gợi ý là cần thiết ngay cả trong Phiên bản Doanh nghiệp để đảm bảo tính duy nhất được cung cấp bởi các chỉ mục chế độ xem được sử dụng bởi trình tối ưu hóa.
Bài viết này xem xét tuyên bố đó và hàm ý của nó một cách chi tiết hơn.
Thiết lập Demo
Tập lệnh sau tạo một bảng đơn giản và dạng xem được lập chỉ mục:
CREATE TABLE dbo.T ( col1 integer NOT NULL ); GO INSERT dbo.T WITH (TABLOCKX) (col1) SELECT SV.number FROM master.dbo.spt_values AS SV WHERE SV.type = N'P'; GO CREATE VIEW dbo.VT WITH SCHEMABINDING AS SELECT T.col1 FROM dbo.T AS T; GO CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.VT (col1);
Điều đó tạo ra một bảng heap cột duy nhất và một chế độ xem không giới hạn của cùng một bảng với một chỉ mục được phân nhóm duy nhất. Đây không phải là một trường hợp sử dụng thực tế cho một chế độ xem được lập chỉ mục; nhưng nó sẽ giúp minh họa những điểm chính mà ít gây xao nhãng nhất. Điểm quan trọng là bảng cơ sở ở đây không có chỉ mục nào cả (thậm chí không phải là chỉ mục được phân cụm) nhưng chế độ xem thì có và chỉ mục đó là duy nhất.
Truy vấn mẫu
Hãy xem xét truy vấn đơn giản sau đối với bảng cơ sở:
SELECT DISTINCT T.col1 FROM dbo.T AS T;
Kế hoạch thực thi bạn sẽ thấy cho truy vấn này tùy thuộc vào phiên bản SQL Server đang sử dụng. Nếu không phải là Phiên bản Doanh nghiệp (hoặc tương đương), bạn sẽ thấy một gói như thế này:
Trình tối ưu hóa truy vấn SQL Server đã chọn quét bảng cơ sở và áp dụng tính riêng biệt được chỉ định bằng cách sử dụng toán tử Sắp xếp Phân biệt. Hình dạng kế hoạch này được mong đợi đầy đủ, vì đối sánh chế độ xem được lập chỉ mục tự động không có sẵn bên ngoài Phiên bản Doanh nghiệp. Tôi sẽ ngừng nói "Phiên bản doanh nghiệp hoặc tương đương" từ thời điểm này trở đi, nhưng hãy tiếp tục suy luận rằng tôi muốn nói đến bất kỳ phiên bản nào hỗ trợ đối sánh chế độ xem tự động khi tôi nói, "Phiên bản doanh nghiệp" kể từ bây giờ.
Gợi ý MỞ RỘNG CHẾ ĐỘ XEM
Đây là một chút sang một bên, nhưng để có được cùng một gói trên Enterprise Edition, chúng tôi cần sử dụng EXPAND VIEWS
gợi ý truy vấn:
SELECT DISTINCT T.col1 FROM dbo.T AS T OPTION (EXPAND VIEWS);
Có vẻ hơi kỳ lạ khi sử dụng gợi ý này khi không có tham chiếu chế độ xem nào trong truy vấn, nhưng đó là cách nó hoạt động. EXPAND VIEWS
gợi ý chỉ định một cách hiệu quả rằng nên tắt đối sánh chế độ xem được lập chỉ mục trong khi biên dịch và tối ưu hóa truy vấn. Nói rõ hơn:Nếu không có gợi ý này, Enterprise Edition có thể khớp (các phần của) truy vấn với một hoặc nhiều chế độ xem được lập chỉ mục.
Đã bật đối sánh chế độ xem tự động
Không có EXPAND VIEWS
gợi ý, việc biên dịch cùng một truy vấn trên Phiên bản dành cho nhà phát triển (ví dụ) sẽ tạo ra một gói khác:
Ứng dụng của đối sánh chế độ xem được lập chỉ mục có nghĩa là kế hoạch thực thi có tính năng quét chỉ mục nhóm chế độ xem thay vì quét bảng cơ sở.
Cùng một kế hoạch được tạo ra trong trường hợp này nếu truy vấn tham chiếu trực tiếp đến chế độ xem (thay vì bảng cơ sở):
SELECT DISTINCT V.col1 FROM dbo.VT AS V;
Trong tất cả các phiên bản, tham chiếu chế độ xem được mở rộng trước khi bắt đầu tối ưu hóa truy vấn. Trong các phiên bản tương đương với Enterprise, biểu mẫu mở rộng có thể được khớp lại với chế độ xem sau này. Đây là khái niệm chính cần hiểu khi nghĩ về cách trình biên dịch truy vấn và trình tối ưu hóa sử dụng các dạng xem được lập chỉ mục trong SQL Server.
Tổng hợp Luồng
Sự khác biệt thú vị nhất giữa hai kế hoạch mà chúng tôi đã thấy cho đến nay là Tổng hợp luồng trong kế hoạch đối sánh chế độ xem. Nếu bạn nhìn vào chi phí ước tính của các toán tử Quét bảng và Quét chế độ xem, bạn sẽ thấy chúng hoàn toàn giống nhau. Trình tối ưu hóa đã không quyết định sử dụng chế độ xem được lập chỉ mục vì nó làm cho việc truy cập dữ liệu trở nên rẻ hơn. Đúng hơn, việc quét chỉ mục chế độ xem cho phép DISTINCT
yêu cầu được triển khai dưới dạng Tổng hợp luồng, chứ không phải là Tổng hợp băm hoặc Sắp xếp riêng (như trong gói đầu tiên).
Một Tổng hợp Luồng yêu cầu đầu vào được sắp xếp theo (các) cột nhóm. Trong trường hợp này, sự khác biệt tương đương với việc nhóm theo cột đơn và chỉ mục được phân nhóm duy nhất của chế độ xem cung cấp sự đảm bảo thứ tự cần thiết. Mô hình chi phí của trình tối ưu hóa xác định Tổng hợp luồng là một tùy chọn rẻ hơn so với Tổng sắp xếp riêng biệt hoặc Tổng hợp băm cho truy vấn này. Đây là cơ sở để trình tối ưu hóa chọn truy cập vào chế độ xem được lập chỉ mục khi tính năng đối sánh chế độ xem tự động khả dụng.
Với tất cả những gì đã nói và đã hiểu, Tổng hợp luồng vẫn không ngờ tới:Với sự đảm bảo về tính duy nhất được cung cấp bởi chỉ mục chế độ xem, không cần thực hiện thao tác nhóm này chút nào. duy nhất chỉ mục nhóm đã đảm bảo cột không chứa trùng lặp.
Tóm lại, đây là vấn đề. Khi đối sánh chế độ xem tự động được sử dụng, trình tối ưu hóa nhận ra đảm bảo thứ tự do chỉ mục chế độ xem cung cấp, nhưng không phải đảm bảo về tính duy nhất.
Sử dụng gợi ý NOEXPAND
Để có được kế hoạch thực thi lý tưởng cho truy vấn này, chúng tôi cần tham chiếu trực tiếp chế độ xem và sử dụng NOEXPAND
gợi ý bảng:
SELECT DISTINCT V.col1 FROM dbo.VT AS V WITH (NOEXPAND);
Điều này cung cấp cho chúng tôi kế hoạch mà một người có kinh nghiệm về cơ sở dữ liệu mong đợi; một công cụ nhận biết chính xác rằng thao tác riêng biệt là dư thừa và có thể bị xóa:
Ví dụ thứ hai
Không tận dụng được đảm bảo tính duy nhất do chỉ mục chế độ xem cung cấp có thể gây ra các ảnh hưởng khác đến kế hoạch thực thi cuối cùng. Bây giờ, hãy xem xét một tự nối của chế độ xem được lập chỉ mục (một lần nữa, chỉ để minh họa một khái niệm - đây không phải là một truy vấn thực tế):
SELECT V1.col1, V2.col1 FROM dbo.VT AS V1 JOIN dbo.VT AS V2 ON V2.col1 = V1.col1;
Sử dụng Phiên bản dành cho nhà phát triển, kế hoạch thực thi đã chọn hoàn toàn không truy cập vào chế độ xem được lập chỉ mục và có tính năng kết hợp băm (đôi khi là dấu hiệu cho thấy thiếu chỉ mục hữu ích):
Bây giờ chúng ta hãy thử chính xác cùng một truy vấn, nhưng với NOEXPAND
gợi ý về mỗi tham chiếu chế độ xem:
SELECT V1.col1, V2.col1 FROM dbo.VT AS V1 WITH (NOEXPAND) JOIN dbo.VT AS V2 WITH (NOEXPAND) ON V2.col1 = V1.col1;
Kế hoạch thực thi hiện có hai quyền truy cập dạng xem được lập chỉ mục và kết hợp hợp nhất:
Kế hoạch mới này có chi phí ước tính thấp hơn nhiều so với kế hoạch tham gia băm, vậy tại sao trình tối ưu hóa không chọn tùy chọn này trước đây? Chúng ta có thể hiểu lý do tại sao bằng cách thêm gợi ý liên kết hợp nhất vào truy vấn ban đầu:
SELECT V1.col1, V2.col1 FROM dbo.VT AS V1 JOIN dbo.VT AS V2 ON V2.col1 = V1.col1 OPTION (MERGE JOIN);
Điều này tạo ra một trông giống nhau kế hoạch chọn truy cập chế độ xem mặc dù NOEXPAND
không được chỉ định:
Chi phí ước tính tổng thể của kế hoạch này cao hơn cả hai ví dụ trước. Hợp nhất trong kế hoạch này cũng chiếm tỷ trọng cao hơn trong tổng chi phí ước tính so với trước đây (98% so với 48,2%).
Lý do cho điều này có thể được nhìn thấy bằng cách xem xét các thuộc tính của phép kết hợp hợp nhất. Trong NOEXPAND
kế hoạch, đó là liên kết hợp nhất một-nhiều. Trong kế hoạch trực tiếp ở trên, nó là một kết hợp nhiều-nhiều. Mô hình chi phí của trình tối ưu hóa chỉ định chi phí cao hơn cho nhiều kết hợp hợp nhất bởi vì cần có một bảng làm việc tempdb để xử lý bất kỳ bản sao nào.
Kết luận
Sự đảm bảo được cung cấp bởi một chỉ mục duy nhất có thể là một công cụ tối ưu hóa mạnh mẽ, vì vậy, thật tiếc là tính năng đối sánh chỉ mục tự động hiện không thể tận dụng nó. Những lợi ích tiềm năng vượt ra ngoài việc loại bỏ các tổng hợp không cần thiết hoặc cho phép liên kết hợp nhất một-nhiều như đã thấy trong các ví dụ đơn giản trước đây. Nói chung, rất khó để phát hiện ra rằng một kế hoạch thực thi là dưới mức tối ưu vì trình tối ưu hóa đã bỏ lỡ việc tận dụng đảm bảo tính duy nhất.
Giới hạn của trình tối ưu hóa này không chỉ áp dụng cho chỉ mục được phân nhóm duy nhất mà một chế độ xem phải có để được hiện thực hóa. Trong các tình huống phức tạp hơn, các chỉ mục không phân bổ bổ sung cũng có thể xuất hiện trên dạng xem; có lẽ để phản ánh các mối quan hệ giữa các bảng khó thực thi hoặc đại diện khác. Nếu các chỉ mục không phân biệt này được xác định là duy nhất, trình tối ưu hóa cũng sẽ bỏ qua các đảm bảo này, nếu sử dụng đối sánh chỉ mục tự động.
Thêm điều này vào những hạn chế xung quanh việc tạo và sử dụng thông tin thống kê, có vẻ như việc dựa vào đối sánh chế độ xem tự động có thể dẫn đến kế hoạch thực thi kém hơn. Tùy chọn an toàn nhất có lẽ là tham chiếu các chế độ xem được lập chỉ mục một cách rõ ràng và sử dụng NOEXPAND
gợi ý mọi lúc - ít nhất là cho đến khi những vấn đề này được giải quyết trong sản phẩm.
Các yếu tố giảm nhẹ
Tôi nên nhấn mạnh rằng vấn đề được mô tả trong bài viết này chỉ áp dụng cho đảm bảo tính duy nhất được cung cấp bởi một chỉ mục chế độ xem duy nhất. Nếu trình tối ưu hóa có thể nhận được thông tin về tính duy nhất được yêu cầu thì một cách khác , rất có thể sẽ tránh được các vấn đề về tối ưu hóa.
Ví dụ, có thể có một chỉ mục duy nhất phù hợp trên một bảng cơ sở được tham chiếu bởi dạng xem. Hoặc, trong trường hợp chế độ xem có chứa tập hợp, trình tối ưu hóa đã có thể suy ra đảm bảo tính duy nhất hữu ích từ GROUP BY
của chế độ xem mệnh đề. Thực tiễn phổ biến là thêm chỉ mục được phân nhóm dạng xem vào các khóa nhóm sẽ không bổ sung thêm thông tin về tính duy nhất trong trường hợp đó.
Tuy nhiên, đôi khi "giám sát tính duy nhất" này có thể có nghĩa là bạn sẽ có được các kế hoạch thực thi chất lượng tốt hơn bằng cách sử dụng tham chiếu chế độ xem rõ ràng và NOEXPAND
gợi ý, ngay cả trong Phiên bản Doanh nghiệp.