SQL Sentry Plan Explorer có đếm số lần đọc trong UDF không?


9

Tôi có một truy vấn như thế này:

select dbo.fn_complexFunction(t.id)
from mytable t

Trong SQL Sentry Plan Explorer, tôi nhận thấy tôi phải chạy Get Ước tính gói trong SQL Sentry để tạo Kế hoạch truy vấn bao gồm UDF.

Khi chạy 'Nhận kế hoạch thực tế', có vẻ như các lần đọc logic và các số liệu khác bao gồm các hoạt động xảy ra trong UDF. Trong trường hợp như thế này, có phải là cách giải quyết duy nhất để sử dụng Profiler không?


1
Theo hiểu biết của tôi, bản thân công cụ truy vấn không có yếu tố đọc trong UDF. Đây là một lý do lớn mà UDF là tốt để tránh, chúng mờ đục cho trình tối ưu hóa.
JNK

Câu trả lời:


11

Từ chối trách nhiệm rõ ràng: Tôi làm việc cho SQL Sentry .

Những vấn đề lớn nhất chúng ta có là:

  1. Giống như @JNK nói, SQL Server làm xáo trộn việc sử dụng UDF và thực hiện mọi thứ khủng khiếp với chúng (như luôn luôn ước tính một hàng). Khi bạn tạo một kế hoạch thực tế trong SSMS, bạn cũng không thấy việc sử dụng nó. Chúng tôi phải chịu những hạn chế tương tự vì chúng tôi chỉ có thể cung cấp thông tin về gói mà SQL Server cung cấp cho chúng tôi.
  2. Chúng tôi dựa vào các nguồn khác nhau cho các số liệu thời gian chạy khi tạo một kế hoạch thực tế. Thật không may, XML của kế hoạch không bao gồm các lệnh gọi hàm và SQL Server không tiết lộ I / O do một hàm phát sinh khi sử dụng SET STATISTICS IO ON;(đây là cách chúng tôi điền vào Table I/Otab của mình).

Hãy xem xét quan điểm và chức năng sau đây đối với AdventureWorks2012. Đây chỉ là một nỗ lực ngớ ngẩn khi trả về một hàng ngẫu nhiên từ bảng chi tiết được cung cấp một hàng ngẫu nhiên từ bảng tiêu đề - chủ yếu để đảm bảo rằng chúng tôi tạo ra càng nhiều I / O càng tốt.

CREATE VIEW dbo.myview 
WITH SCHEMABINDING
AS
  SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID() 
    FROM Sales.SalesOrderDetail ORDER BY NEWID();
GO

CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
RETURNS UNIQUEIDENTIFIER
WITH SCHEMABINDING
AS
BEGIN
  RETURN 
  (
    SELECT TOP (1) rowguid FROM dbo.myview 
     WHERE SalesOrderID = @SalesOrderID ORDER BY n
  );
END
GO

Studio quản lý làm gì (và không) cho bạn biết

Thực hiện truy vấn sau trong SSMS:

SET STATISTICS IO ON;

  SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID) 
    FROM Sales.SalesOrderHeader ORDER BY NEWID();

SET STATISTICS IO OFF;

Khi bạn ước tính một kế hoạch, bạn nhận được một kế hoạch cho truy vấn một kế hoạch duy nhất cho chức năng (không phải 5, như bạn có thể hy vọng):

Kế hoạch dự kiến ​​trong Studio quản lý

Rõ ràng, bạn không nhận được bất kỳ dữ liệu I / O nào vì truy vấn không thực sự được thực thi. Bây giờ, tạo ra một kế hoạch thực tế. Bạn nhận được 5 hàng bạn mong đợi trong lưới kết quả, kế hoạch sau (hoàn toàn không đề cập đến UDF, ngoại trừ trong XML bạn có thể tìm thấy nó như một phần của văn bản truy vấn và là một phần của Toán tử vô hướng):

Kế hoạch thực tế trong Studio quản lý

STATISTICS IOđầu ra sau đây (mà hoàn toàn không đề cập đến Sales.SalesOrderDetail, mặc dù chúng tôi biết rằng nó phải đọc từ bảng đó):

Bảng 'SalesOrderHeader'. Quét số 1, đọc logic 57, đọc vật lý 0, đọc trước đọc 0, đọc logic 0, đọc vật lý lob 0, đọc trước đọc 0, đọc trước 0.

Nhà thám hiểm nói gì với bạn

Khi chúng tôi tạo một kế hoạch ước tính cho cùng một truy vấn, chúng tôi biết về điều tương tự như SSMS. Tuy nhiên, chúng tôi cho thấy mọi thứ một cách trực quan hơn một chút. Ví dụ, kế hoạch ước tính cho truy vấn bên ngoài cho thấy kết quả đầu ra của hàm được kết hợp với đầu ra của truy vấn và rõ ràng ngay lập tức - trong một sơ đồ kế hoạch duy nhất - có I / O từ cả hai bảng :

Kế hoạch dự kiến ​​trong Plan Explorer

Chúng tôi cũng chỉ hiển thị kế hoạch của hàm , mà tôi chỉ bao gồm để hoàn thiện:

Kế hoạch dự kiến ​​cho UDF trong Plan Explorer

Bây giờ, chúng ta hãy xem một kế hoạch thực tế, hữu ích hơn hàng ngàn lần. Nhược điểm ở đây là, một lần nữa, chúng tôi chỉ có thông tin mà SQL Server quyết định hiển thị, vì vậy chúng tôi chỉ có thể hiển thị (các) sơ đồ kế hoạch đồ họa mà SQL Server cung cấp cho chúng tôi. Đây không phải là tình huống mà chúng tôi quyết định không cho bạn thấy điều gì hữu ích; chúng tôi thực sự không biết gì về nó dựa trên kế hoạch XML được cung cấp cho chúng tôi. Trong trường hợp này, giống như trong SSMS, chúng ta chỉ thấy kế hoạch của truy vấn bên ngoài và như thể hàm này không được gọi ở tất cả :

Kế hoạch thực tế trong Plan Explorer

Tab Bảng I / O của chúng ta cũng vậy, vẫn dựa vào đầu ra củaSTATISTICS IO , bảng này cũng bỏ qua mọi hoạt động được thực hiện trong lệnh gọi hàm:

Bảng I / O cho kế hoạch thực tế trong Plan Explorer

Tuy nhiên, chúng tôi nhận được toàn bộ ngăn xếp cuộc gọi cho bạn. Thỉnh thoảng tôi nghe mọi người hỏi, "Pffft, khi nào tôi sẽ cần ngăn xếp cuộc gọi?" Chúng tôi thực sự có thể chia nhỏ thời gian sử dụng, CPU được sử dụng và số lần đọc (và, đối với TVF, số lượng hàng được tạo) cho mỗi lệnh gọi hàm duy nhất :

Ngăn xếp cuộc gọi trong Plan Explorer, hiển thị các cuộc gọi UDF

Thật không may, chúng tôi không có khả năng tương quan trở lại (các) I / O đến từ bảng nào (vì SQL Server không cung cấp cho chúng tôi thông tin đó) và nó không được gắn nhãn với tên UDF (bởi vì nó được ghi lại như một câu lệnh ad hoc, không phải là hàm gọi chính nó). Nhưng những gì nó cho phép bạn thấy, Management Studio không, đó là con chó mà UDF của bạn đang là gì. Bạn vẫn phải tham gia một số dấu chấm, nhưng có ít dấu chấm hơn và chúng gần nhau hơn.

Giới thiệu về hồ sơ

Cuối cùng, tôi thực sự khuyên bạn nên tránh xa Profiler, trừ khi phải thiết lập một dấu vết phía máy chủ mà bạn sẽ chạy bên ngoài phạm vi của bất kỳ công cụ UI nào. Sử dụng Profiler chống lại một hệ thống sản xuất gần như chắc chắn sẽ gây ra nhiều vấn đề hơn nó sẽ giải quyết . Nếu bạn muốn có được thông tin này, vui lòng sử dụng theo dõi phía máy chủ hoặc các sự kiện mở rộng và đảm bảo lọc rất khôn ngoan. Ngay cả khi không có hồ sơ, một dấu vết có thể tác động đến máy chủ của bạn và truy xuất các chương trình thông qua các sự kiện mở rộng cũng không phải là điều hiệu quả nhất trên thế giới .


À, tôi không biết về ngăn xếp cuộc gọi trong phiên bản Pro. Đó chính xác là những gì tôi đang tìm kiếm. Thật tốt khi biết điều đó tồn tại. Tại thời điểm này, tôi không nghĩ rằng tôi có thể biện minh cho giá nhưng tôi sẽ ghi nhớ nó cho các tình huống trong tương lai. Có lý do tại sao SQL Server không cung cấp thông tin I / O cho UDF trong STATISTICS IO không? Đó là sai lầm để bỏ qua thông tin cần thiết như vậy.
Gabe

3
@Gabe Tôi không biết lý do, xin lỗi. Có lẽ để làm cho tư vấn sinh lợi hơn?
Aaron Bertrand

1
@gabe hiện có kế hoạch explorer hoàn toàn miễn phí .. được gọi là sentry one có tất cả các tính năng phiên bản pro + cuối cùng - tất cả đều miễn phí.
Kin Shah
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.