2013-12-10 12 views
6

Recentemente ho dato un'iniziativa in cui l'intervistatore mi ha chiesto di spiegare la differenza più semplice tra Stored Procedure e UDF.Stored procedure vs Compilation funzioni e differenza di prestazioni

Sono riuscito a richiamare un paio di differenze come listed here ma non ha accettato nessuna di esse come la differenza BASIC.

risposta secondo lui era che SP di sono compilati solo una volta, mentre UDF vengono compilati ogni volta essi sono chiamati con conseguente UDF di essere notevolmente più lento di stored procedure.

Ora ho cercato, ma non poteva ottenere una chiara risposta taglio se questa affermazione è vera. Si prega di verificare questo.

+0

So che le righe stimate contano per un UDF è 1 tutto il tempo ... –

+0

Hanno torto. Le UDF non vengono ricompilate ogni volta che vengono chiamate. Questo è possibile provare diversi modi. per esempio. traccia (ri) compilare gli eventi nel profiler, guarda i DMV in cache del piano. [La mia risposta qui] (http://stackoverflow.com/questions/19884138/why-sql-functions-are-faster-than-udf/19891697#19891697) esamina le tracce dello stack durante l'esecuzione di UDF più volte. Il sovraccarico è durante l'esecuzione non la compilazione. –

+0

Che tipo di funzione - valutata in scala scalare o in riga o multistrato?I tre sono diversi tipi di oggetti con diversi meccanismi di esecuzione (i TVF in linea sono in linea, ad esempio :-). –

risposta

5

@mhasan, grazie per il riferimento al mio post sul blog nella tua domanda.

Per quanto un so stored procedure & Funzioni entrambi hanno lo stesso comportamento in termini di compilazione & ricompilazione. Entrambi sono non precompilati. Quando crei uno di questi vengono solo analizzati e creati, ma non compilati. Entrambi sono compilati quando vengono eseguiti per la prima volta. E potrebbero essere ricompilati automaticamente di nuovo se vengono applicati dei cambiamenti.

Eseguire query seguente dopo aver creato una nuova funzione:

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

Si vedrà un solo record, che è il piano compilato di per questa query stessa, vale a dire un Adhoc Object-Type.

Dopo aver eseguito la funzione rre-eseguire nuovamente questa query. Vedrete più record tra cui il piano compilato della funzione, che ha un oggetto di tipo Proc.

Spero che questo aiuti.

+0

grazie manaoj bhai .. Ho inserito il tuo blog tra i preferiti ... imparerà molto da lì. –

+0

Grazie Hasan, mi piacerebbe averti come mio lettore. –

4

Questa è un'affermazione strana e per quanto ne so UDF e SP vengono compilati (e ricompilati quando cambia) allo stesso modo. Sembra che l'intervistatore abbia mescolato le UDF con query dinamiche (non parametriche). Se qualcuno trova una piccola informazione per sostenere tale argomento, per favore segnalalo.

+0

Per aggiungere, sì UDF scalare può essere lento e una buona lezione su di esso è questo articolo e la discussione seguita. http://www.sqlservercentral.com/articles/T-SQL/91724/ – jean

3

Jean ha ragione sono compilati definitivamente una volta.

seguente query vi darà la cache delle procedure e includere metriche utili come numero di esecuzioni, si legge, ecc:

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 

Nel rapporto sono in grado di vedere le funzioni con un'esecuzione contano superiore a 1. In altre parole il piano di esecuzione esistente viene riutilizzato. Stesso comportamento delle stored procedure.