En nuestra base de datos de SQL Server 2005 (probado con Administración Estudio con DBCC FREEPROCCACHE
y DBCC DROPCLEANBUFFERS
), la siguiente declaración es rápido (~ 0,2 segundos de tiempo de compilación, ~ tiempo de 0,1 segundos de ejecución):Evitar el uso de ADO.NET sp_executesql
SELECT ... FROM ... WHERE a = 1 AND b = '' ...
la siguiente declaración, sin embargo, es lento (~ 0,2 segundos de tiempo de compilación, 7-11s tiempo de ejecución):
exec sp_executesql N'SELECT ... FROM ... WHERE a = @a AND b = @b ...', N'@a int, @b nvarchar(4000), ...', @a=1, @b=N'', ...
SQL Server elige un plan de ejecución diferente, aunque las consultas son iguales. Esto tiene sentido, ya que, en el primer caso, SQL Server tiene los valores reales de a
, b
y todos los demás parámetros disponibles y puede usar las estadísticas para crear un mejor plan. Aparentemente, el plan de consulta para los valores concretos de los parámetros es mucho mejor que el genérico y definitivamente supera cualquier beneficio de rendimiento de "caché de planes de consulta".
Ahora mi pregunta: ADO.NET siempre parece usar la segunda opción (sp_executesql) al ejecutar consultas parametrizadas, lo que suele ser tiene sentido (caché de plan de consulta, etc.). En nuestro caso, sin embargo, esto mata el rendimiento. Entonces, ¿hay alguna manera de cualquiera
- fuerza de ADO.NET para usar algo diferente a
sp_executesql
(es decir, algo donde el analizador de consultas de SQL Server toma los valores reales de los parámetros en cuenta) O - fuerza de SQL Server para volver a recapitular el plan de consulta del SQL pasado a
sp_executesql
tomando los valores de los parámetros en la cuenta?
Y por favor, no me diga que tengo que volver a feo, viejo, peligroso sql = "WHERE b = " + quoteAndEscape(parameterB)
...
Poner el SQL en un procedimiento almacenado hace ninguna diferencia (lento, con y sin WITH RECOMPILE
) . No publiqué el enunciado de SQL real ya que es bastante complejo (se une a varias tablas, incluidos los sub-SELECT y la agregación).
convirtiéndolo en un procedimiento almacenado es tan lenta como la consulta ad hoc? Este es un comportamiento MUY extraño, así que debo preguntar: ¿estás seguro? –
@Rubens: ¿por qué dices eso? ¿Qué ventaja de rendimiento ofrece un procedimiento almacenado sobre una consulta ad hoc en caché, compilada y parametrizada? –
Sí, estoy seguro. ¿Por qué debería ser más rápido? El tiempo de compilación es insignificantemente pequeño (0.2s) en comparación con el tiempo de ejecución (7-11s). – Heinzi