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à:
- 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.
- 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/O
tab 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 và 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):
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):
Và 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 :
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:
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ả :
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:
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 :
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 .