2013-12-10 47 views
6

最近我给了一个inetrview,其中面试官要求我解释存储过程和UDF之间最基本的区别。存储过程与函数编译和性能差异

我能回忆起几个作为listed here分歧,但他没有接受任何人的BASIC差异。

根据他的回答是,SP只编译一次,而UDF的每次被调用时都会被编译,导致UDF比存储过程慢很多。

现在我已经搜索,但无法得出明确的答案,这个断言是否属实。 请验证这一点。

+0

我知道UDF的估计行数始终为1 ... –

+0

他们错了。每次调用UDF时都不会重新编译它们。这有可能证明一些方法。例如在分析器中跟踪(重新)编译事件,查看缓存DMV的计划。 [我的答案在这里](http://stackoverflow.com/questions/19884138/why-sql-functions-are-faster-than-udf/19891697#19891697)多次执行UDF时会查看堆栈跟踪。开销在执行期间不编译。 –

+0

什么样的函数 - 标量或内联表值或多语句表值?三者是具有不同执行机制的不同类型的对象(内联TVF是内联的,例如:-)。 –

回答

5

@mhasan,谢谢你提到我的博客文章在你的问题。

据一个我知道存储过程 & 功能两者在编译&重新编译的条款相同的行为。两者都是未预先编制。当你创建其中的一个时,他们只是被解析和创建,但没有被编译。它们都是在第一次执行时编译的。如果对它们进行了更改,它们可以再次自动重新编译。

执行以下查询创建一个新的功能后:

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%' 

你会看到只有一个记录,这是的编译计划为这个查询本身,即自组织对象类型。

执行函数rre后再次执行此查询。你会看到更多的记录,包括函数的编译计划,它具有对象类型的过程。

希望这会有所帮助。

+0

感谢manaoj bhai ..我已经为您的博客添加了书签...将会从那里学到很多东西。 –

+0

谢谢哈桑,很想让你成为我的读者。 –

4

这是一个奇怪的声明,据我所知,UDF和SP被编译(并且在它改变时重新编译)。它显示你面试官与UDF混合动态(非参数)查询。如果有人发现一些微小的信息来维持这一论点,请报告。

+0

要添加,yep Scalar UDF可能会很慢,关于它的一个很好的演讲是本文和随后的讨论。 http://www.sqlservercentral.com/articles/T-SQL/91724/ – jean

3

吉恩是正确的,他们肯定编译过一次。

以下查询会给你的程序缓存和包括有用的指标,如执行次数,读取等:

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 

在我能够看到与执行功能大于1计数高报告换句话说,现有的执行计划被重用。与存储过程相同的行为。

相关问题