2011-12-02 33 views
5

Sử dụng MSSQL 2005udf vs hiệu suất sql trực tiếp

Tôi đã chơi xung quanh ngày hôm nay với một Scalar UDF trong một nơi tuyên bố để xem một số các chi phí liên quan thực hiện cuộc gọi và những khác biệt io, vv

tôi m bắt đầu với 2 bảng cơ bản. Khách hàng có 1 triệu hàng. và các giao dịch mua có 100.000. Cả hai đều có một cột nhận dạng tự động là khóa chính. Không có chỉ mục nào khác được xác định.

DBCC FREEPROCCACHE 
DBCC DROPCLEANBUFFERS 

SET STATISTICS IO ON 
    SELECT * FROM Customer C 
    INNER JOIN Purchases P on C.[IDENTITY] = P.CustomerID 
    WHERE P.Amount > 1000 
SET STATISTICS IO OFF 

này trả về thống kê IO của

Table 'Customer'. Scan count 0, logical reads 3295, physical reads 1, read-ahead reads 32, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'Purchases'. Scan count 1, logical reads 373, physical reads 1, read-ahead reads 370, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Vì vậy, chỉ để xem tác động của một UDF vô hướng sau đó tôi chỉ di chuyển P.Amount> 1000 đến một UDF. Chức năng như sau:

CREATE FUNCTION [dbo].[HighValuePurchase] 
(
    @value int 
) 
RETURNS bit 
AS 
BEGIN 
    DECLARE @highValue bit 
    SET @highValue = '0' 

    IF @value > 1000 
    BEGIN 
     SET @highValue = '1' 
    END 
    RETURN @highValue 
END 

Vì vậy, tôi sau đó chạy các truy vấn sau đây:

DBCC FREEPROCCACHE 
DBCC DROPCLEANBUFFERS 

SET STATISTICS IO ON  
    SELECT * FROM Customer C 
    INNER JOIN Purchases P on C.[IDENTITY] = P.CustomerID 
    WHERE dbo.HighValuePurchase(P.Amount) = '1' 
SET STATISTICS IO OFF 

tôi đã mong đợi này để chạy tồi tệ hơn. Truy vấn này trả lại số liệu thống kê IO sau:

Table 'Purchases'. Scan count 1, logical reads 373, physical reads 1, read-ahead reads 370, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'Customer'. Scan count 1, logical reads 35, physical reads 3, read-ahead reads 472, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Điều này cũng trả về nhanh hơn truy vấn> 1000. Trong khi các hàng giống nhau được trả về, thứ tự của một gọi là UDF được sắp xếp tự động bởi C. [IDENTITY] trong đó truy vấn khác xuất hiện chưa được phân loại. Điều này có khả năng là do cách kết hợp được thực hiện trong các kế hoạch thực hiện. Phác thảo các kế hoạch dưới đây.

Kế hoạch thực hiện cho UDF không hiển thị quét chỉ mục cụm cho các giao dịch mua và chỉ mục cụm được tìm kiếm cho khách hàng được kết hợp tại tham gia lồng nhau.

Kế hoạch thực hiện cho phiên bản UDF hiển thị quét chỉ mục nhóm cho các giao dịch mua, sau đó là một bộ lọc, sau đó sắp xếp. Có một nhóm chỉ mục quét trên khách hàng. Sau đó, kết quả được kết hợp trong một Merge Join.

Tôi chắc chắn điều này có liên quan đến việc thiếu chỉ mục, v.v. nhưng tôi không chắc tại sao các kết quả này lại như vậy. Tôi đã có kinh nghiệm của UDF chạy chậm chạp và mọi người nói rằng sử dụng chúng thường là một ý tưởng tồi, đó là lý do tại sao tôi đã thử nghiệm này với nhau. Tôi không thể giải thích tại sao phiên bản UDF có vẻ tốt hơn nhiều.

+0

Tìm hiểu một số thông tin liên quan đến điều này: http://sqlinthewild.co.za/index.php/2009/04/29/functions-io-statistics-and-the-execution-plan/ Tôi vẫn có thể ' t có được số liệu thống kê "đúng" IO cho truy vấn trên, nhưng điều này ít nhất cũng giúp giải thích nó. – Equixor

+0

Có vẻ như bạn sẽ không nhận được câu trả lời trên diễn đàn này. Có thể muốn đăng trên một trang web cụ thể hơn sql. I E. http://www.sqlservercentral.com/Forums/ –

+0

lý do tại sao bạn sẽ đặt tên cho một cột là IDENTITY ??? tại sao không chỉ đặt tên cho nó là CustomerID trong cả hai bảng ??? đặt tên những thứ như thế này chỉ giết người nghèo tiếp theo sẽ phải làm việc trên hệ thống này sau bạn. –

Trả lời

1
  • Nếu bạn muốn tham gia Purchases.CustomerID bạn nên đặt chỉ mục trên đó.
  • Nếu bạn thường truy vấn trên phạm vi giá trị, bạn cũng nên đặt chỉ mục trên đó.

Vì bạn đang yêu cầu máy chủ SQL chọn giữa hai gói xấu.

Máy chủ SQL có thể đoán số lượng giao dịch mua sẽ được bao gồm trong truy vấn > 1000 và sẽ chọn gói dựa trên đó.

Tuy nhiên, nó không thể đoán số lượng sẽ được bao gồm bởi truy vấn UDF, vì vậy có thể chọn một gói khác. Bởi vì nó đang xảy ra sự thiếu hiểu biết, nó có thể tốt hơn hoặc tệ hơn so với kế hoạch khác tùy thuộc vào mức độ dự đoán của nó.

Bạn có thể xem các gói đã tạo và nó sẽ cho bạn biết số hàng ước tính trong mỗi gói và cũng là số thực. Những con số ước tính này cho phép lựa chọn kế hoạch trong từng trường hợp.

Các vấn đề liên quan