Giới thiệu
Công cụ biểu diễn là những ống lười được trình tối ưu hóa thêm vào để giảm chi phí ước tính của mặt bên trong trong tổng số các phép nối vòng lặp lồng nhau . Chúng có ba loại: Lazy Table Spool , Lazy Index Spool và Ống đếm hàng lười biếng . Dưới đây là một hình dạng sơ đồ ví dụ hiển thị một ống hiệu suất bảng lười:
Các câu hỏi tôi đặt ra để trả lời trong bài viết này là tại sao, cách thức và thời điểm trình tối ưu hóa truy vấn giới thiệu từng loại ống hiệu suất.
Ngay trước khi chúng ta bắt đầu, tôi muốn nhấn mạnh một điểm quan trọng:Có hai kiểu tham gia vòng lặp lồng nhau khác nhau trong các kế hoạch thực thi. Tôi sẽ đề cập đến sự đa dạng với tài liệu tham khảo bên ngoài như một áp dụng và loại có vị từ nối trên chính toán tử kết hợp dưới dạng tham gia vòng lặp lồng nhau . Để rõ ràng, sự khác biệt này là về các nhà khai thác kế hoạch thực thi , không phải cú pháp truy vấn T-SQL. Để biết thêm chi tiết, vui lòng xem bài viết được liên kết của tôi.
Công cụ hỗ trợ hiệu suất
Hình ảnh dưới đây cho thấy ống hiệu suất toán tử kế hoạch thực thi như được hiển thị trong Plan Explorer (hàng trên cùng) và SSMS 18.3 (hàng dưới):
Nhận xét chung
Tất cả cuộn hiệu suất lười biếng . Bàn làm việc của ống cuộn dần dần được điền vào, một hàng tại một thời điểm, khi các hàng truyền qua ống chỉ. (Ngược lại, các cuộn dây háo hức sử dụng tất cả đầu vào từ toán tử con của chúng trước khi trả về bất kỳ hàng nào cho cha mẹ của chúng).
Các cuộn hiệu suất luôn xuất hiện ở mặt trong (đầu vào thấp hơn trong các kế hoạch thực thi đồ họa) của một toán tử áp dụng hoặc tham gia các vòng lồng nhau. Ý tưởng chung là lưu vào bộ nhớ cache và phát lại kết quả, lưu các lần thực thi lặp lại của các toán tử bên trong bất cứ khi nào có thể.
Khi cuộn có thể phát lại các kết quả đã lưu trong bộ nhớ cache, điều này được gọi là tua lại . Khi cuộn phải thực thi các toán tử con của nó để có được dữ liệu chính xác, một rebind xảy ra.
Bạn có thể thấy hữu ích khi nghĩ về một ống cuộn rebind như một lần bỏ lỡ bộ nhớ cache và một tua lại như một lần truy cập vào bộ nhớ cache.
Lazy Table Spool
Loại ống hiệu suất này có thể được sử dụng với cả áp dụng và tham gia các vòng lặp lồng nhau .
Áp dụng
A rebind (bỏ lỡ bộ nhớ cache) xảy ra bất cứ khi nào một tham chiếu bên ngoài giá trị thay đổi. Một ống chỉ lười gắn lại bằng cách cắt bớt bảng làm việc của nó và tạo lại hoàn toàn nó từ các toán tử con của nó.
Đ tua lại (lần truy cập bộ nhớ cache) xảy ra khi phía bên trong thực thi với cùng một giá trị tham chiếu bên ngoài làm ngay trước lặp vòng lặp. Tua lại phát lại các kết quả đã lưu trong bộ nhớ cache từ bảng làm việc của bộ đệm, tiết kiệm chi phí thực hiện lại các toán tử kế hoạch bên dưới bộ đệm.
Lưu ý:Bộ đệm bảng lười chỉ lưu vào bộ nhớ cache các kết quả cho một tập hợp áp dụng tài liệu tham khảo bên ngoài các giá trị tại một thời điểm.
Tham gia các vòng lặp lồng nhau
Cuộn bảng lười được điền một lần trong lần lặp vòng lặp đầu tiên. Spool tua lại nội dung của nó cho mỗi lần lặp tiếp theo của phép nối. Với phép nối các vòng lặp lồng nhau, phía bên trong của phép nối là một tập hợp các hàng tĩnh vì vị từ phép nối nằm trên chính phép nối. Do đó, tập hợp hàng bên trong tĩnh có thể được lưu vào bộ nhớ đệm và sử dụng lại nhiều lần thông qua bộ đệm. Một ống hiệu suất tham gia vòng lặp lồng nhau không bao giờ liên kết lại.
Ống đếm hàng lười
Một ống chỉ số hàng nhiều hơn một chút so với một Ống chỉ bảng không có cột. Nó lưu trữ sự tồn tại của một hàng, nhưng không hiển thị dữ liệu cột. Ngoài việc ghi nhận sự tồn tại của nó và đề cập rằng nó có thể là dấu hiệu của lỗi trong truy vấn nguồn, tôi sẽ không nói thêm về các cuộn đếm số hàng.
Từ thời điểm này trở đi, bất cứ khi nào bạn nhìn thấy “ống bảng” trong văn bản, vui lòng đọc nó là “ống chỉ bảng (hoặc số hàng)” vì chúng rất giống nhau.
Lazy Index Spool
Lazy Index Spool nhà điều hành chỉ khả dụng khi áp dụng .
Ống chỉ mục duy trì một bảng làm việc không bị cắt ngắn khi tham chiếu bên ngoài giá trị thay đổi. Thay vào đó, dữ liệu mới được thêm vào bộ đệm hiện có, được lập chỉ mục bởi các giá trị tham chiếu bên ngoài. Ống chỉ mục lười khác với ống chỉ mục lười ở chỗ nó có thể phát lại kết quả từ bất kỳ lặp lại vòng lặp trước, không chỉ là vòng lặp gần đây nhất.
Bước tiếp theo để hiểu khi nào các cuộn hiệu suất xuất hiện trong các kế hoạch thực thi đòi hỏi bạn phải hiểu một chút về cách hoạt động của trình tối ưu hóa.
Nền của Trình tối ưu hóa
Truy vấn nguồn được chuyển đổi thành biểu diễn cây logic bằng cách phân tích cú pháp, đại số hóa, đơn giản hóa và chuẩn hóa. Khi cây kết quả không đủ điều kiện cho một kế hoạch tầm thường, trình tối ưu hóa dựa trên chi phí sẽ tìm kiếm các lựa chọn thay thế hợp lý được đảm bảo tạo ra cùng kết quả, nhưng với chi phí ước tính thấp hơn.
Khi trình tối ưu hóa đã tạo ra các giải pháp thay thế tiềm năng, nó sẽ triển khai từng giải pháp thay thế bằng cách sử dụng các toán tử vật lý thích hợp và tính toán chi phí ước tính. Kế hoạch thực hiện cuối cùng được xây dựng từ tùy chọn chi phí thấp nhất được tìm thấy cho mỗi nhóm người vận hành. Bạn có thể đọc thêm chi tiết về quy trình này trong loạt bài Tìm hiểu sâu về Trình tối ưu hóa Truy vấn của tôi.
Các điều kiện chung cần thiết để ống hiệu suất xuất hiện trong kế hoạch cuối cùng của trình tối ưu hóa là:
- Trình tối ưu hoá phải khám phá một giải pháp thay thế hợp lý bao gồm ống cuộn hợp lý trong một thay thế được tạo. Điều này phức tạp hơn nghe, vì vậy tôi sẽ giải nén các chi tiết trong phần chính tiếp theo.
- Thư viện logic phải có thể triển khai như một ống chỉ vật lý toán tử trong công cụ thực thi. Đối với các phiên bản SQL Server hiện đại, điều này về cơ bản có nghĩa là tất cả các cột chính trong một ống chỉ mục phải thuộc loại có thể so sánh được nhập, tổng cộng không quá 900 byte *, có 64 cột chính trở xuống.
- Tốt nhất kế hoạch hoàn chỉnh sau khi tối ưu hóa dựa trên chi phí phải bao gồm một trong các lựa chọn thay thế ống chỉ. Nói cách khác, bất kỳ lựa chọn dựa trên chi phí nào được thực hiện giữa các tùy chọn ống cuộn và không có ống lót đều phải có lợi cho ống đệm.
* Giá trị này được mã hóa cứng vào SQL Server và không bị thay đổi sau khi tăng lên 1700 byte cho nonclustered khóa chỉ mục từ SQL Server 2016 trở đi. Điều này là do chỉ mục cuộn là một cụm chỉ mục, không phải chỉ mục không hợp nhất.
Quy tắc Trình tối ưu hóa
Chúng tôi không thể chỉ định ống đệm bằng T-SQL, vì vậy việc có một ống trong kế hoạch thực thi có nghĩa là trình tối ưu hóa phải chọn để thêm nó. Ở bước đầu tiên, điều này có nghĩa là trình tối ưu hóa phải bao gồm một cuộn hợp lý vào một trong những lựa chọn thay thế mà nó chọn để khám phá.
Trình tối ưu hóa không áp dụng đầy đủ tất cả các quy tắc tương đương lôgic mà nó biết cho mọi cây truy vấn. Điều này sẽ lãng phí, do mục tiêu của trình tối ưu hóa là tạo ra một kế hoạch hợp lý một cách nhanh chóng. Có nhiều khía cạnh cho điều này. Đầu tiên, trình tối ưu hóa tiến hành theo từng giai đoạn, với các quy tắc rẻ hơn và thường xuyên hơn được thử trước. Nếu một kế hoạch hợp lý được tìm thấy trong giai đoạn đầu hoặc truy vấn không đủ điều kiện cho các giai đoạn sau, nỗ lực tối ưu hóa có thể kết thúc sớm với kế hoạch chi phí thấp nhất được tìm thấy cho đến nay. Chiến lược này giúp ngăn việc dành nhiều thời gian hơn cho việc tối ưu hóa hơn là tiết kiệm được bằng cách cải thiện chi phí gia tăng.
Đối sánh quy tắc
Mỗi toán tử logic trong cây truy vấn được nhanh chóng kiểm tra xem có khớp mẫu với các quy tắc có sẵn trong giai đoạn tối ưu hóa hiện tại hay không. Ví dụ:mỗi quy tắc sẽ chỉ khớp với một tập hợp con các toán tử logic và cũng có thể yêu cầu các thuộc tính cụ thể phải có, chẳng hạn như đầu vào được sắp xếp đảm bảo. Một quy tắc có thể phù hợp với một hoạt động logic riêng lẻ (một nhóm) hoặc nhiều nhóm liền kề (một phần con của kế hoạch).
Sau khi đối sánh, quy tắc ứng cử viên được yêu cầu tạo giá trị hứa hẹn . Đây là con số thể hiện khả năng quy tắc hiện tại tạo ra kết quả hữu ích, dựa trên bối cảnh cục bộ. Ví dụ:một quy tắc có thể tạo ra giá trị hứa hẹn cao hơn khi mục tiêu có nhiều bản sao trên đầu vào, số lượng hàng ước tính lớn, đầu vào được sắp xếp đảm bảo hoặc một số thuộc tính mong muốn khác.
Khi các quy tắc thăm dò đầy hứa hẹn đã được xác định, trình tối ưu hóa sẽ sắp xếp chúng theo thứ tự giá trị hứa hẹn và bắt đầu yêu cầu chúng tạo các sản phẩm thay thế hợp lý mới. Mỗi quy tắc có thể tạo ra một hoặc nhiều thay thế mà sau này sẽ được thực hiện bằng cách sử dụng các toán tử vật lý. Là một phần của quá trình đó, chi phí ước tính sẽ được tính toán.
Điểm của tất cả điều này khi nó áp dụng cho các cuộn hiệu suất là hình dạng và thuộc tính của kế hoạch hợp lý phải có lợi cho việc phù hợp với các quy tắc có khả năng tạo cuộn và ngữ cảnh cục bộ phải tạo ra giá trị hứa hẹn đủ cao mà trình tối ưu hóa chọn để tạo ra các sản phẩm thay thế bằng cách sử dụng quy tắc .
Quy tắc Spool
Có một số quy tắc khám phá tham gia các vòng lặp lồng nhau hợp lý hoặc áp dụng các lựa chọn thay thế. Một số quy tắc này có thể tạo ra một hoặc nhiều sản phẩm thay thế với một loại ống hiệu suất cụ thể. Các quy tắc khác phù hợp với các vòng lặp lồng nhau tham gia hoặc áp dụng không bao giờ tạo ra một thay thế ống đệm.
Ví dụ:quy tắc ApplyToNL
triển khai một áp dụng hợp lý như một vòng lặp vật lý tham gia với các tham chiếu bên ngoài. Quy tắc này có thể tạo ra một số lựa chọn thay thế mỗi lần nó chạy. Ngoài toán tử kết hợp vật lý, mỗi phép thay thế có thể chứa một cuộn bảng lười, một cuộn chỉ mục lười hoặc không có cuộn nào cả. Các thay thế cuộn hợp lý sau đó được triển khai riêng lẻ và được định giá như các cuộn vật lý được định kiểu thích hợp, bởi một quy tắc khác được gọi là BuildSpool
.
Ví dụ thứ hai, quy tắc JNtoIdxLookup
triển khai một phép nối lôgic dưới dạng một áp dụng vật lý , với một chỉ mục tìm kiếm ngay lập tức ở phía bên trong. Quy tắc này không bao giờ tạo ra một thay thế với một thành phần ống chỉ. JNtoIdxLookup
được đánh giá sớm và trả về giá trị hứa hẹn cao khi nó khớp, do đó, các kế hoạch tra cứu chỉ mục đơn giản được tìm thấy nhanh chóng.
Khi trình tối ưu hóa tìm thấy một giải pháp thay thế chi phí thấp như thế này sớm, các lựa chọn thay thế phức tạp hơn có thể bị loại bỏ hoặc bỏ qua hoàn toàn. Lý do là không có ý nghĩa gì khi theo đuổi các lựa chọn không có khả năng cải thiện trên một phương án thay thế chi phí thấp đã được tìm thấy. Tương tự, sẽ không đáng để khám phá thêm nếu kế hoạch hoàn chỉnh tốt nhất hiện tại đã có tổng chi phí đủ thấp.
Ví dụ về quy tắc thứ ba:Quy tắc JNtoNL
tương tự như ApplyToNL
, nhưng nó chỉ triển khai nối vòng lặp lồng nhau vật lý , có ống chỉ lười hoặc không có ống. Quy tắc này không bao giờ tạo một ống chỉ mục vì loại ống đó yêu cầu áp dụng.
Tạo và định phí ống đệm
Quy tắc có khả năng việc tạo ra một cuộn hợp lý sẽ không nhất thiết phải làm như vậy mỗi khi nó được gọi. Sẽ là lãng phí nếu tạo ra các lựa chọn thay thế hợp lý mà bên cạnh đó không có cơ hội được chọn là rẻ nhất. Ngoài ra còn có chi phí để tạo ra các giải pháp thay thế mới, từ đó có thể tạo ra nhiều lựa chọn thay thế hơn - mỗi lựa chọn trong số đó có thể cần thực hiện và tốn kém.
Để quản lý điều này, trình tối ưu hóa triển khai logic chung cho tất cả các quy tắc có khả năng cuộn để xác định (các) loại thay thế ống đệm nào sẽ tạo dựa trên các điều kiện gói cục bộ.
Tham gia các vòng lặp lồng nhau
Đối với một tham gia các vòng lồng nhau , cơ hội nhận được ống lót bàn lười tăng tương ứng với:
- Số hàng ước tính ở đầu vào bên ngoài của phép nối.
- Chi phí ước tính của các nhà khai thác gói bên trong.
Chi phí của ống chỉ được hoàn trả bằng cách tiết kiệm tránh thực hiện bên trong của người vận hành. Tiết kiệm tăng lên với nhiều lần lặp lại bên trong hơn và chi phí bên trong cao hơn. Điều này đặc biệt đúng bởi vì mô hình chi phí chỉ định số I / O và chi phí CPU tương đối thấp cho các vòng tua của ống đệm bảng (số lần truy cập bộ nhớ cache). Hãy nhớ rằng cuộn bảng trên các vòng lặp lồng nhau chỉ tham gia vào các lần tua lại, bởi vì việc thiếu tham số có nghĩa là tập dữ liệu bên trong là tĩnh.
Bộ đệm có thể lưu trữ dữ liệu mật độ cao hơn so với các toán tử cung cấp nó. Ví dụ:một chỉ mục nhóm trong bảng cơ sở có thể lưu trữ trung bình 100 hàng trên mỗi trang. Giả sử truy vấn chỉ cần một giá trị cột số nguyên duy nhất từ mỗi hàng chỉ mục được phân cụm rộng. Chỉ lưu trữ giá trị số nguyên trong bảng làm việc cuộn có nghĩa là hơn 800 hàng như vậy có thể được lưu trữ trên mỗi trang. Điều này quan trọng vì trình tối ưu hóa đánh giá chi phí của ống bảng một phần bằng cách sử dụng ước tính số trang bảng làm việc cần thiết. Các yếu tố chi phí khác bao gồm chi phí CPU trên mỗi hàng liên quan đến việc ghi và đọc ống đệm, trên số lần lặp lại vòng lặp ước tính.
Trình tối ưu hóa được cho là hơi quá quan tâm đến việc thêm các cuộn bảng lười biếng vào bên trong của một phép nối các vòng lặp lồng nhau. Tuy nhiên, quyết định của trình tối ưu hóa luôn có ý nghĩa về chi phí ước tính. Cá nhân tôi coi việc tham gia các vòng lặp lồng nhau là rủi ro cao , bởi vì chúng có thể nhanh chóng trở nên chậm nếu ước tính số lượng bản số tham gia quá thấp.
Một ống chỉ bàn có thể giúp giảm chi phí, nhưng nó không thể che giấu hoàn toàn hiệu suất trong trường hợp xấu nhất của một phép nối các vòng lặp lồng nhau ngây thơ. Một phép nối áp dụng được lập chỉ mục thường thích hợp hơn và có khả năng phục hồi tốt hơn đối với các lỗi ước tính. Bạn cũng nên viết các truy vấn mà trình tối ưu hóa có thể triển khai bằng phép băm hoặc phép kết hợp khi thích hợp.
Áp dụng Lazy Table Spool
Để áp dụng , cơ hội nhận được ống lót bàn lười tăng với số lượng ước tính trùng lặp nối các giá trị chính trên đầu vào bên ngoài của ứng dụng. Với nhiều bản sao hơn, có một thống kê cơ hội cao hơn để cuộn chỉ tua lại các kết quả hiện được lưu trữ của nó trên mỗi lần lặp. Áp dụng bộ đệm bảng lười với chi phí ước tính thấp hơn có cơ hội tốt hơn để làm nổi bật trong kế hoạch thực thi cuối cùng.
Khi các hàng đến trên đầu vào bên ngoài áp dụng không có thứ tự cụ thể, trình tối ưu hóa thực hiện một đánh giá thống kê về khả năng mỗi lần lặp lại dẫn đến việc tua lại rẻ hay tua lại đắt. Đánh giá này sử dụng dữ liệu từ các bước biểu đồ khi có sẵn, nhưng ngay cả tình huống tốt nhất này cũng là một phỏng đoán có học thức hơn. Nếu không có bảo đảm, thứ tự các hàng đến trên đầu vào bên ngoài áp dụng là không thể đoán trước.
Các quy tắc tương tự của trình tối ưu hóa tạo ra các lựa chọn thay thế ống hợp lý có thể cũng có thể chỉ định rằng toán tử áp dụng yêu cầu hàng đã sắp xếp trên đầu vào bên ngoài của nó. Điều này tối đa hóa ống lười tua lại bởi vì tất cả các bản sao được đảm bảo sẽ gặp phải trong một khối. Khi thứ tự sắp xếp đầu vào bên ngoài được đảm bảo, bằng cách giữ nguyên thứ tự hoặc một Sắp xếp rõ ràng , giá thành của ống chỉ giảm đi nhiều. Các yếu tố của trình tối ưu hóa trong tác động của thứ tự sắp xếp đến số vòng tua và tua lại của cuộn chỉ.
Các kế hoạch có Sắp xếp trên đầu vào bên ngoài áp dụng và Bộ đệm bảng Lazy trên đầu vào bên trong là khá phổ biến. Việc tối ưu hóa sắp xếp bên ngoài có thể vẫn phản tác dụng. Ví dụ:điều này có thể xảy ra khi ước tính số lượng bên ngoài thấp đến mức sắp xếp kết thúc tràn xuống tempdb .
Áp dụng Lazy Index Spool
Để áp dụng , nhận được ống chỉ mục lười biếng thay thế phụ thuộc vào hình dạng kế hoạch cũng như chi phí.
Trình tối ưu hóa yêu cầu:
- Một số trùng lặp nối các giá trị trên đầu vào bên ngoài.
- Một bình đẳng tham gia vị từ (hoặc tương đương logic mà trình tối ưu hóa hiểu, chẳng hạn như
x <= y AND x >= y
). - Đ bảo đảm rằng các tham chiếu bên ngoài là duy nhất bên dưới ống chỉ mục lười được đề xuất.
Trong các kế hoạch thực thi, tính duy nhất được yêu cầu thường được cung cấp bởi một nhóm tổng hợp bởi các tham chiếu bên ngoài, hoặc một tập hợp vô hướng (một nhóm không có nhóm bởi). Tính duy nhất cũng có thể được cung cấp theo những cách khác, ví dụ như bằng cách tồn tại một chỉ mục hoặc ràng buộc duy nhất.
Dưới đây là một ví dụ đồ chơi thể hiện hình dạng kế hoạch:
CREATE TABLE #T1 ( c1 integer NOT NULL ); GO INSERT #T1 (c1) VALUES -- Duplicate outer rows (1), (2), (3), (4), (5), (6), (1), (2), (3), (4), (5), (6), (1), (2), (3), (4), (5), (6); GO SELECT * FROM #T1 AS T1 CROSS APPLY ( SELECT COUNT_BIG(*) FROM (SELECT T1.c1 UNION SELECT NULL) AS U ) AS CA (c);
Lưu ý đến Tổng hợp luồng bên dưới Lazy Index Spool .
Nếu các yêu cầu về hình dạng kế hoạch được đáp ứng, trình tối ưu hóa thường sẽ tạo ra một thay thế chỉ mục lười biếng (tùy thuộc vào các cảnh báo đã đề cập trước đó). Kế hoạch cuối cùng có bao gồm cuộn chỉ mục lười biếng hay không phụ thuộc vào chi phí.
Index Spool so với Table Spool
Số lượng tua lại ước tính và rebinds đối với cuộn chỉ mục lười thì giống nhau như đối với một ống lười để bàn không có đã sắp xếp áp dụng đầu vào bên ngoài.
Đây có vẻ như là một trạng thái khá đáng tiếc. Ưu điểm chính của ống chỉ mục là nó lưu trữ tất cả các kết quả đã thấy trước đó. Điều này phải làm cho cuộn chỉ mục tua lại nhiều khả năng hơn là đối với một cuộn bảng (không có phân loại đầu vào bên ngoài) trong các trường hợp tương tự. Tôi hiểu rằng điều kỳ lạ này tồn tại bởi vì nếu không có nó, trình tối ưu hóa sẽ chọn một cuộn chỉ mục quá thường xuyên.
Bất kể, mô hình chi phí điều chỉnh cho những điều trên ở một mức độ nào đó bằng cách sử dụng số I / O và CPU hàng ban đầu và tiếp theo khác nhau cho các cuộn chỉ mục và bảng. Hiệu quả thực sự là một ống chỉ mục thường có giá thấp hơn một ống chỉ mục không có đầu vào bên ngoài được sắp xếp, nhưng hãy nhớ các yêu cầu về hình dạng kế hoạch hạn chế, khiến cho các cuộn chỉ mục lười biếng tương đối hiếm.
Tuy nhiên, đối thủ cạnh tranh về chi phí chính đối với chỉ số ống lười là ống chỉ bảng với đầu vào bên ngoài được sắp xếp. Trực giác cho điều này là khá đơn giản:Đầu vào bên ngoài được sắp xếp có nghĩa là cuộn bảng được đảm bảo để xem tất cả các tham chiếu bên ngoài trùng lặp một cách tuần tự. Điều này có nghĩa là nó sẽ rebind chỉ một lần cho mỗi giá trị riêng biệt và tua lại cho tất cả các bản sao. Điều này giống như hành vi mong đợi của một cuộn chỉ mục (ít nhất là theo logic).
Trong thực tế, một cuộn chỉ mục có nhiều khả năng được ưu tiên hơn một cuộn bảng được tối ưu hóa sắp xếp để có ít giá trị khóa áp dụng trùng lặp hơn. Việc có ít khóa trùng lặp hơn sẽ giảm tua lại lợi thế của cuộn bảng được tối ưu hóa sắp xếp, so với các ước tính ống chỉ mục “không may” đã được lưu ý trước đây.
Tùy chọn ống chỉ mục cũng có lợi vì chi phí ước tính của ống chỉ bảng bên ngoài Sắp xếp tăng. Điều này thường được kết hợp với nhiều hàng hơn (hoặc rộng hơn) tại thời điểm đó trong kế hoạch.
Dấu vết và Gợi ý
-
Các ống hiệu suất có thể bị vô hiệu hóa với cờ theo dõi được ghi chép nhẹ 8690 hoặc gợi ý truy vấn được lập thành văn bản
NO_PERFORMANCE_SPOOL
trên SQL Server 2016 trở lên. -
Cờ theo dõi không có giấy tờ 8691 có thể được sử dụng (trên hệ thống thử nghiệm) để luôn thêm ống hiệu suất khi có thể. Loại không thể ép buộc ống lười mà bạn nhận được (số hàng, bảng hoặc chỉ mục); nó vẫn phụ thuộc vào ước tính chi phí.
-
Cờ theo dõi không có giấy tờ 2363 có thể được sử dụng với mô hình ước tính bản số mới để xem kết quả của ước tính riêng biệt ở đầu vào bên ngoài để áp dụng và ước tính bản số nói chung.
-
Cờ theo dõi không có giấy tờ 9198 có thể được sử dụng để vô hiệu hóa các cuộn hiệu suất chỉ mục lười đặc biệt. Thay vào đó, bạn vẫn có thể nhận được bảng lười hoặc cuộn đếm hàng (có hoặc không có tối ưu hóa sắp xếp), tùy thuộc vào chi phí.
-
Cờ theo dõi không có giấy tờ 2387 có thể được sử dụng để giảm chi phí CPU đọc các hàng từ ống chỉ mục lười biếng . Cờ này ảnh hưởng đến ước tính chi phí CPU chung để đọc một loạt các hàng từ cây b. Cờ này có xu hướng làm cho việc lựa chọn ống chỉ mục có nhiều khả năng hơn, vì lý do chi phí.
Bạn có thể tìm thấy các phương pháp và cờ theo dõi khác để xác định quy tắc trình tối ưu hóa nào đã được kích hoạt trong quá trình biên dịch truy vấn trong loạt bài Deep Dive về Trình tối ưu hóa truy vấn của tôi.
Kết luận
Có rất nhiều chi tiết nội bộ ảnh hưởng đến việc kế hoạch thực thi cuối cùng có sử dụng ống hiệu suất hay không. Tôi đã cố gắng đề cập đến những vấn đề chính trong bài viết này mà không đi quá sâu vào các chi tiết cực kỳ phức tạp của các công thức tính chi phí toán tử ống. Hy vọng rằng có đủ lời khuyên chung ở đây để giúp bạn xác định các lý do có thể xảy ra đối với một loại ống hiệu suất cụ thể trong một kế hoạch thực thi (hoặc thiếu chúng).
Tôi nghĩ công bằng mà nói thì những người thực hiện màn trình diễn thường bị rap tệ. Một số điều này chắc chắn là xứng đáng. Nhiều người trong số các bạn sẽ thấy một bản demo trong đó một kế hoạch thực hiện nhanh hơn mà không có “ống hiệu suất” so với với. Ở một mức độ nào đó, điều đó không nằm ngoài dự đoán. Các trường hợp cạnh tồn tại, mô hình chi phí không hoàn hảo và chắc chắn các bản trình diễn thường đưa ra các kế hoạch với ước tính bản số kém hoặc các vấn đề hạn chế trình tối ưu hóa khác.
Điều đó nói rằng, đôi khi tôi ước SQL Server sẽ cung cấp một số loại cảnh báo hoặc phản hồi khác khi nó sử dụng thêm một cuộn bảng lười vào một phép nối vòng lặp lồng nhau (hoặc một ứng dụng không có chỉ mục bên trong hỗ trợ được sử dụng). Như đã đề cập trong phần nội dung chính, đây là những tình huống tôi thường thấy sai nghiêm trọng nhất, khi các ước tính về cardinality trở nên thấp khủng khiếp.
Có lẽ một ngày nào đó, trình tối ưu hóa truy vấn sẽ tính đến một số khái niệm rủi ro để lập kế hoạch lựa chọn hoặc cung cấp nhiều khả năng "thích ứng" hơn. Trong thời gian chờ đợi, nó sẽ trả tiền để hỗ trợ các vòng lặp lồng nhau của bạn tham gia với các chỉ mục hữu ích và để tránh viết các truy vấn chỉ có thể được thực hiện bằng cách sử dụng các vòng lặp lồng nhau nếu có thể. Tất nhiên, tôi đang tổng quát hóa, nhưng trình tối ưu hóa có xu hướng hoạt động tốt hơn khi có nhiều lựa chọn hơn, lược đồ hợp lý, siêu dữ liệu tốt và các câu lệnh T-SQL có thể quản lý được để làm việc. Tôi cũng vậy, hãy nghĩ về nó.
Các bài viết về ống dẫn khác
Các cuộn không hiệu suất được sử dụng cho nhiều mục đích trong SQL Server, bao gồm:
- Bảo vệ Halloween
- Một số chức năng của cửa sổ chế độ hàng
- Tính toán nhiều tổng hợp
- Tối ưu hóa các câu lệnh làm thay đổi dữ liệu