temporales - ¿Por qué SQL Server va lento cuando se usan variables?
variables @@ sql server (7)
¿El ID está en un índice (por ejemplo, clave principal)? Si no, intente agregar uno.
Otra cosa podría ser que en la primera instancia (rápida) la consulta se ejecuta de forma ligeramente diferente. Lo más común que he visto pasar es que las uniones se realizan en un orden ineficiente. Intente reordenar las uniones o convierta algunas a subconsultas. Si publica más de su consulta, podemos ayudarlo más.
Tengo una consulta sql que se ejecuta muy rápido, alrededor de un segundo, cuando no se usan variables, como:
WHERE id BETWEEN 5461094 and 5461097
Pero cuando tengo:
declare @firstId int
declare @lastId int
set @firstId = 5461094
set @lastId = 5461097
...
WHERE id BETWEEN @firstId and @lastId
... la consulta se ejecuta realmente lento, terminando solo después de algunos minutos. ¿Por que sucede? Necesito usar variables. ¿Puedo hacer alguna mejora para evitar estos problemas de rendimiento?
Es porque cuando los valores están codificados, puede buscar las estadísticas que tiene en los datos en la tabla y descubrir la mejor consulta para ejecutar. Eche un vistazo a los planes de ejecución de cada una de estas consultas. Debe estar escaneando cuando usa variables.
si el rango es siempre pequeño, es posible que pueda usar una sugerencia de índice para ayudarlo.
DE ACUERDO,
- Usted es el Optimizador y el Plan de Consulta es un vehículo.
- Le daré una consulta y tendrá que elegir el vehículo.
- Todos los libros en la biblioteca tienen un número secuencial
Mi consulta es Ir a la biblioteca y obtener todos los libros entre 3 y 5
Escogerías una bicicleta correcta, rápida, barata, eficiente y lo suficientemente grande como para llevar 3 libros.
Nueva consulta.
Vaya a la biblioteca y obtenga todos los libros entre @x y @y.
Elige el vehículo.
Adelante.
Eso es lo que sucede. ¿Escoges un camión de basura en caso de que pida libros entre 1 y Maxvalue? Eso es exagerado si x = 3 ey = 5. SQL tiene que elegir el plan antes de ver los números.
Es gracioso que este código sea rápido también:
DECLARE @sql VARCHAR(8000)
SET @sql = ''SELECT * FROM table_x WHERE id BETWEEN '' + CAST(@firstId AS VARCHAR) + '' AND '' + CAST(@lastId AS VARCHAR)
EXEC (@sql)
(MSSQL 2000)
Si esas variables son variables de entrada para un proceso almacenado, podría encontrarse con el problema del rastreo de parámetros. http://omnibuzz-sql.blogspot.com/2006/11/parameter-sniffing-stored-procedures.html
Parece que esta consulta está relacionada con un procedimiento almacenado, su plan de ejecución se compilará la primera vez que se ejecuta el proceso y luego se reutilizará para las siguientes ejecuciones.
Es posible que el plan compilado sea realmente malo para las situaciones en las que firstid está realmente cerca de lastid, sin embargo es realmente bueno cuando los valores están muy separados.
Intente habilitar la opción WITH RECOMPILE en su proceso almacenado. Si resuelve el problema y está satisfecho con el proceso que se vuelve a compilar cada vez que se ejecuta (obtendrá un golpe de rendimiento) déjelo ahí. Si aún no está satisfecho con el rendimiento, considere volver a diseñar el proceso para que no necesite la compilación.
En realidad, fue respondida muy bien, solo escribo aquí una solución ya que funcionó para mí:
Crear un procedimiento almacenado con el SQL
WHERE id BETWEEN @firstId and @lastId
Luego, llame al proceso almacenado con los parámetros @firstId y @lastId y se acelerará. Todavía no estoy 100% de por qué está funcionando, pero funciona.