2013-12-10 14 views
6

Gần đây tôi đã đưa ra một inetrview trong đó người phỏng vấn yêu cầu tôi giải thích sự khác biệt cơ bản nhất giữa thủ tục lưu trữ và UDF.Lưu trữ thủ tục vs Chức năng biên dịch và hiệu suất khác biệt

Tôi đã có thể gọi lại một số khác biệt là listed here nhưng anh ấy không chấp nhận bất kỳ sự kiện nào trong số đó là sự khác biệt BASIC.

Trả lời theo ông là SP chỉ được biên dịch một lần trong khi UDF được biên dịch mỗi khi chúng được gọi là kết quả UDF chậm hơn đáng kể so với quy trình được lưu trữ.

Bây giờ tôi đã tìm kiếm nhưng không thể nhận được câu trả lời rõ ràng cho dù xác nhận này có đúng không. Vui lòng xác minh điều này.

+0

Tôi biết rằng số hàng ước tính được tính cho UDF là 1 lần ... –

+0

Chúng sai. Các UDF không được biên dịch lại mỗi khi chúng được gọi. Điều này có thể chứng minh một số cách. ví dụ. theo dõi (tái) các sự kiện biên dịch trong hồ sơ, xem xét kế hoạch bộ đệm ẩn DMV. [Câu trả lời của tôi ở đây] (http://stackoverflow.com/questions/19884138/why-sql-functions-are-faster-than-udf/19891697#19891697) xem xét các dấu vết ngăn xếp khi thực thi UDF nhiều lần. Chi phí là trong quá trình thực hiện không biên dịch. –

+0

Loại hàm nào - vô hướng hoặc giá trị bảng có giá trị nhiều bảng hoặc bảng nội tuyến?Ba loại này là các kiểu đối tượng khác nhau với các cơ chế thực hiện khác nhau (các TVF nội tuyến được inlined, ví dụ :-). –

Trả lời

5

@mhasan, cảm ơn vì đã đề cập đến bài đăng trên blog của tôi trong câu hỏi của bạn.

Theo một Tôi biết Stored Procedure & Chức năng cả hai đều có cùng một hành vi về biên soạn & biên dịch lại. Cả hai đều là chưa được biên dịch trước. Khi bạn tạo một trong số chúng, chúng chỉ được phân tích và tạo ra, nhưng không được biên dịch. Cả hai đều được biên dịch khi chúng được thực hiện lần đầu tiên. Và chúng có thể được tự động biên dịch lại nếu có bất kỳ thay đổi nào được áp dụng cho chúng.

Execute truy vấn sau đây sau khi bạn tạo một chức năng mới:

SELECT objtype, cacheobjtype, usecounts, text 
FROM sys.dm_exec_cached_plans AS p 
     CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) AS t 
WHERE t.text LIKE '%YourNewFunctionName%' 

Bạn sẽ thấy chỉ có một kỷ lục, đó là kế hoạch biên soạn của cho truy vấn này chính nó, ví dụ: một Adhoc Object-Type.

Sau khi thực thi hàm sẽ thực hiện lại truy vấn này. Bạn sẽ thấy nhiều bản ghi hơn bao gồm kế hoạch biên dịch của hàm, trong đó có một Object-Type of Proc.

Hy vọng điều này sẽ hữu ích.

+0

cảm ơn manaoj bhai .. Tôi đã đánh dấu blog của bạn ... sẽ học hỏi được rất nhiều từ đó. –

+0

Cảm ơn Hasan, rất muốn có bạn là người đọc của tôi. –

4

Đó là một câu lệnh kỳ lạ và theo tôi biết UDF và SP được biên soạn (và biên dịch lại khi nó thay đổi) như nhau. Nó xuất hiện cho bạn phỏng vấn UDF hỗn hợp với các truy vấn động (không tham số). Nếu ai đó tìm thấy một thông tin nhỏ để duy trì lập luận đó, hãy báo cáo.

+0

Để thêm, yep Scalar UDF có thể được làm chậm và một bài giảng tốt về nó là bài viết này và thảo luận tiếp theo. http://www.sqlservercentral.com/articles/T-SQL/91724/ – jean

3

Jean đúng, chúng chắc chắn được biên dịch một lần.

Tiếp theo truy vấn sẽ cung cấp cho bạn bộ nhớ cache thủ tục và bao gồm các số liệu hữu ích như đếm thực hiện, đọc, vv:

SELECT TOP 1000 DB_NAME(qt.dbid)           AS DB, 
       OBJECT_NAME(qt.objectid, qt.dbid)      AS 'object_name', 
       qs.total_worker_time, 
       qs.execution_count, 
       qs.total_logical_reads, 
       plan_generation_num, 
       SUBSTRING(qt.text, (qs.statement_start_offset/2) + 1, 
            ((CASE statement_end_offset 
              WHEN -1 THEN DATALENGTH(qt.text) 
              ELSE qs.statement_end_offset 
              END - qs.statement_start_offset)/2) + 1) AS 'query' 
FROM sys.dm_exec_query_stats AS qs 
     CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt 
     LEFT JOIN sys.objects o 
     ON o.object_id = qt.objectid 
WHERE qs.execution_count > 0 
     AND DATEDIFF(Second, qs.creation_time, GETDATE()) > 0 
     AND DATEDIFF(Minute, qs.creation_time, GETDATE()) > 0 
ORDER BY /*Sort functions first*/ 
      CASE 
      WHEN o.type_desc LIKE '%FUNCTION' THEN 0 
      ELSE 1 
      END, 
      qs.execution_count DESC 

Trong báo cáo tôi có thể thấy chức năng với thực hiện đếm cao hơn 1. Trong các từ khác, kế hoạch thực thi hiện có được sử dụng lại. Hành vi tương tự như với các thủ tục được lưu trữ.

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