Usando MSSQL 2005UDF vs rendimiento de SQL directa
Yo estaba jugando hoy con un escalar UDF en un comunicado, donde para ver algunos de los costos asociados con la fabricación de la llamada y io diferencias etc.
I' m comenzando con 2 tablas básicas. Cliente que tiene 1 millón de filas. y compras que tiene 100,000. Ambos tienen una columna de identidad automática como clave principal. No hay otros índices definidos.
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
Esto devuelve las estadísticas de IO
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.
lo tanto, sólo para ver el impacto de una UDF escalar Entonces acabo de mudar el P.Amount> 1000 a una UDF. Función es la siguiente:
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
Así que corrió la siguiente consulta:
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
me esperaba esto para ejecutar peor. Esta consulta devuelve los siguientes estadísticas IO:
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.
Esto también volvieron más rápido que la> 1000 consulta. Mientras se devolvían las mismas filas, el orden del que llamaba a la UDF se ordenaba automáticamente por C. [IDENTIDAD], donde la otra consulta no estaba ordenada. Esto probablemente se deba a la forma en que se hicieron las combinaciones en los planes de ejecución. El esquema de los planes está a continuación.
El plan de ejecución para el UDF no muestra un análisis de índice agrupado para compras y una búsqueda de índice agrupado para clientes combinados en una combinación anidada.
El plan de ejecución para la versión UDF muestra un análisis de índice agrupado para compras, luego un filtro y luego un ordenamiento. Hay un escaneo indexado agrupado en el cliente. Luego, los resultados se combinan en una combinación de combinación.
Estoy seguro de que esto tiene que ver con la falta de índices, etc., pero no estoy seguro de por qué estos resultados son los que son. Experimenté que la UDF funcionaba con lentitud y todos dicen que usarlas generalmente es una mala idea, y es por eso que hice esta prueba juntos. No puedo explicar por qué la versión UDF parece ser mucho mejor.
Encontré algo de información relacionada con esto: http://sqlinthewild.co.za/index.php/2009/04/29/functions-io-statistics-and-the-execution-plan/ Todavía puedo ' Obtenga las estadísticas de IO "verdaderas" para la consulta anterior, pero esto al menos ayuda a explicarlo. – Equixor
Parece que no va a obtener una respuesta en este foro. Es posible que desee publicar en un sitio específico más sql. es decir. http://www.sqlservercentral.com/Forums/ –
¿por qué demonios nombrarías una columna IDENTIDAD? ¿por qué no solo nombrarlo CustomerID en ambas tablas? nombrar cosas como esta simplemente mata a la próxima persona pobre que tendrá que trabajar en este sistema después de ti. –