Kế hoạch truy vấn ước tính so với thực tế với các cuộc gọi chức năng


11

Tôi có truy vấn này trên máy chủ SQL, một truy vấn sao chép hợp nhất:

SELECT DISTINCT
    b.tablenick,
    b.rowguid,
    c.generation,
    sys.fn_MSgeneration_downloadonly
    (
        c.generation,
        c.tablenick
    )
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON 
    c.tablenick = b.tablenick
    AND c.rowguid = b.rowguid;

Gói truy vấn ước tính bao gồm thông tin về 3 truy vấn:

  1. Các truy vấn trên
  2. Hàm gọi tới fn_MSgeneration_doadonly
  3. Hàm gọi tới fn_MSArticle_has_doadonly_property

Gói truy vấn thực tế chỉ bao gồm thông tin này:

  1. Các truy vấn trên

Không có gì về các chức năng. Tại sao thông tin chức năng bị thiếu trong kế hoạch thực tế?

Tôi đã thử các tùy chọn sau:

SET STATISTICS PROFILE ON
SET STATISTICS XML ON

Điều này đã tạo ra một kế hoạch thực tế, nhưng nó thiếu phần 2 và 3 giống như khi tôi sử dụng tùy chọn kế hoạch truy vấn thực tế trong Management Studio.

Ví dụ, nếu tôi sử dụng Profiler để nắm bắt thông tin về hàm thì tôi sẽ chọn sự kiện nào?


Không tìm thấy câu trả lời cụ thể liên quan đến các gói truy vấn, nhưng tôi đã mô tả SP: StmtStarting và SP: StmtCompleted và nó hiển thị các lệnh gọi hàm.

Câu trả lời:


17

Và không có gì về các chức năng. Tại sao thông tin chức năng bị thiếu trong kế hoạch thực tế?

Đây là do thiết kế, vì lý do hiệu suất.

Các hàm chứa BEGINENDtrong định nghĩa tạo khung ngăn xếp T-SQL mới cho mỗi hàng đầu vào. Nói cách khác, thân hàm được thực thi riêng cho từng hàng đầu vào . Thực tế duy nhất này giải thích hầu hết các vấn đề về hiệu năng liên quan đến các hàm vô hướng và đa câu lệnh T-SQL (lưu ý rằng các hàm có giá trị trong bảng trong dòng không sử dụng BEGIN...ENDcú pháp).

Trong ngữ cảnh câu hỏi của bạn, điều này sẽ dẫn đến SHOWPLANđầu ra đầy đủ cho mỗi hàng. Sản lượng kế hoạch XML khá dài dòng và tốn kém để sản xuất, do đó, sản xuất đầy đủ đầu ra cho mỗi hàng sẽ là một ý tưởng tồi trong các thuật ngữ chung.

Thí dụ

Hãy xem xét hàm vô hướng T-SQL bên dưới, được tạo trong cơ sở dữ liệu mẫu AdventureWorks , trả về tên của sản phẩm được cung cấp ID của nó:

CREATE FUNCTION dbo.DumbNameLookup
(
    @ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
    RETURN
    (
        SELECT
            p.Name
        FROM Production.Product AS p
        WHERE
            p.ProductID = @ProductID
    );
END;

Kế hoạch trước khi thực hiện

Một kế hoạch thực hiện trước (kế hoạch ước tính trong SSMS) hiển thị thông tin kế hoạch cho câu lệnh cha và các lệnh gọi hàm lồng nhau:

-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;

Đầu ra SSMS:

Kế hoạch tiền thực hiện SSMS

Cùng một XML được xem trong SQL Sentry Plan Explorer cho thấy bản chất lồng nhau của các cuộc gọi rõ ràng hơn:

Kế hoạch tiền thực hiện PE

Đầu ra sau thực hiện

SSMS chỉ hiển thị chi tiết cho truy vấn chính khi yêu cầu đầu ra của kế hoạch hậu thực hiện:

-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;

SSMS hậu thực hiện

Tác động hiệu năng của việc làm khác có thể được hiển thị bằng Lớp Sự kiện Cấu hình Thống kê XML Showplan trong SQL Server Profiler, sử dụng truy vấn gọi hàm nhiều lần (một lần cho mỗi hàng đầu vào):

SELECT TOP (5)
    p.ProductID,
    dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;

Hồ sơ đầu ra:

Đầu ra dấu vết

Có năm kế hoạch hậu thực hiện riêng biệt cho việc thực thi chức năng và một kế hoạch cho truy vấn cha. Năm kế hoạch chức năng trông như thế này trong khung bên dưới hồ sơ:

Kế hoạch chức năng

Kế hoạch truy vấn cha là:

Kế hoạch phụ huynh

Thực hiện truy vấn mà không có TOP (5)mệnh đề dẫn đến một kế hoạch thực hiện đầy đủ cho mỗi trong số 504 hàng trong bảng Sản phẩm. Bạn có thể thấy làm thế nào điều này sẽ nhanh chóng ra khỏi tầm tay với các bảng lớn hơn.

Tình hình cho các kích hoạt được đảo ngược. Chúng không hiển thị bất kỳ thông tin kế hoạch trước khi thực hiện, nhưng bao gồm một kế hoạch sau thực hiện. Điều này phản ánh bản chất dựa trên tập hợp của các kích hoạt; mỗi cái được bắn một lần cho tất cả các hàng bị ảnh hưởng, thay vì một lần trên mỗi hàng.


@PaulWhite có lý do chính đáng nào để các kế hoạch kích hoạt không được hiển thị khi yêu cầu kế hoạch thực hiện ước tính không? Đó dường như là một tính năng thiếu hữu ích. Tôi có thể tạo một mục kết nối cho nó.
usr

@usr - Có thể vì gói bộ nhớ cache thực tế được chọn có thể thay đổi tùy thuộc vào số lượng hàng thực tế như được mô tả ở đây? technet.microsoft.com/en-us/l Library / từ
Martin Smith

@MartinSmith đó có thể là một lý do. Gần đây, một mục kết nối cho các kế hoạch thực hiện kiểm tra và ràng buộc fk đã được đánh dấu là đã hoàn thành, vì vậy tôi hy vọng họ sẽ làm điều tương tự với các trình kích hoạt.
usr

@usr - Cái này đây ? 3 tháng? Đó phải là một bản ghi quay vòng cho một yêu cầu tính năng mới!
Martin Smith

@MartinSmith có, cái đó. Nó đã được "sửa" 1-2 trước. Tôi thực sự hy vọng tôi không phải truy vấn cửa hàng truy vấn. Tôi đã hy vọng nhấp vào một nút trong SSMS. Trên thực tế, tôi đã rất ngạc nhiên khi thấy bất kỳ thay đổi nào đối với một phần của động cơ đã không được chạm vào trong nhiều năm. Nhưng có lẽ không có ai.
usr
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.