Tengo un procedimiento almacenado que devuelve los resultados de una vista indexada a través de un índice de cobertura. Por lo general, funciona rápido (~ 10 ms), a veces puede durar hasta 8 segundos.
Aquí hay un ejemplo de ejecución aleatoria (nota: esta no es lenta, pero el texto de la consulta es el mismo aparte del valor pasado):
declare @p2 dbo.IdentityType
insert into @p2 values(5710955)
insert into @p2 values(5710896)
insert into @p2 values(5710678)
insert into @p2 values(5710871)
insert into @p2 values(5711103)
insert into @p2 values(6215197)
insert into @p2 values(5710780)
exec ListingSearch_ByLocationAndStatus @statusType=1,@locationIds=@p2
Aquí está el SPROC:
ALTER PROCEDURE [dbo].[ListingSearch_ByLocationAndStatus]
@LocationIds IdentityType READONLY,
@StatusType TINYINT
AS
BEGIN
SET NOCOUNT ON;
SELECT -- lots of fields
FROM [dbo].[ListingSearchView][a] WITH (NOEXPAND)
INNER JOIN @LocationIds [b] ON [a].[LocationId] = [b].[Id]
WHERE [a].[StatusType] = @statusType
OPTION (RECOMPILE);
(nota: agregué la OPTION (RECOMPILE)
pista recientemente después de algunos consejos, pero no ha ayudado.
Aquí está el índice de cobertura (nota: la vista también tiene un índice agrupado ListingId
, que es único)
CREATE NONCLUSTERED INDEX [IX_ListingSearchView_ForAPI] ON [dbo].[ListingSearchView]
(
[LocationId] ASC,
[StatusType] ASC
)
INCLUDE ( -- all the fields in the query) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
Puse un rastreador de perfil, con estadísticas de showplan XML.
Aquí hay uno lento (6 segundos) y el plan relevante:
Se ve exactamente como esperaba, y es el mismo plan cuando la consulta es rápida.
Aquí está el acercamiento a la parte costosa del plan, si eso ayuda:
Aquí está el esquema completo de las tablas de vista / respaldo, si eso ayuda: https://pastebin.com/wh1sRcbQ
Notas:
- Los índices han sido desfragmentados, las estadísticas actualizadas.
- Originalmente, la consulta estaba en línea con la vista, pero me mudé a SPROC para tratar de ayudar a estabilizar. No ha ayudado
- Agregar
WITH OPTION (RECOMPILE);
sugerencia (no funcionó, ¿no puede ser el rastreo de parámetros?) - Otras consultas en el sistema también a veces se ejecutan lentamente, y tampoco tienen problemas obvios en su plan.
- Podría estar bloqueando? No estoy seguro de cómo confirmar.
¿Alguna idea de lo que podría probar a continuación?
Gracias
Respuestas:
Realmente no creo que usarlo
OPTION (RECOMPILE)
sea una forma efectiva de eliminar la posibilidad de olfatear parámetros.El rastreo de parámetros ocurre cuando SQL está confundido acerca de una consulta en particular y piensa que es nuevo porque ve nuevos parámetros. Es lento porque lleva tiempo adicional generar un nuevo plan de ejecución.
Todo lo que hace esa opción es forzar a SQL a producir un nuevo plan cada vez que es más o menos lo mismo. En cambio, es posible que desee considerar agregar parámetros predeterminados utilizando esta sugerencia:
Al elegir los parámetros por defecto, asegúrese de utilizar un conjunto estadísticamente representativo.
Eso obligará a usar el mismo plan cada vez y eliminará la posibilidad de olfatear parámetros. Una vez que haga eso, y determine que no ayudó, entonces probablemente sea seguro descartar la inhalación de parámetros como una posibilidad.
fuente
Quizás intente forzar el orden, por lo que probablemente siempre comience con la tabla más pequeña (variable). Sin embargo, eso es complicado con las vistas ...
o puede forzar una unión en bucle si generalmente es así como desea unir la variable de tabla a la vista, lo que también forzará el orden ...
fuente
Escriba el nombre del procedimiento Store en el Editor de consultas, luego seleccione el proceso Store. nombre y luego seleccione Visualizar plan de ejecución estimada o haga clic (Ctrl + L). debajo de la imagen de esto.
luego, Planes de ejecución se muestra justo al lado de la pestaña Mensajes en la parte inferior del Editor de consultas. luego, en las líneas de color verde, muestre los detalles del índice que faltan y haga clic derecho sobre eso. Luego Nueva consulta abierta en una nueva pestaña y luego crear el ÍNDICE entonces su consulta se ejecuta rápidamente.
Así que utilicé este método para diagnosticar la consulta que trabaja lentamente. y también hay tantas consultas o métodos que puedes usar.
fuente
Si cree que el problema está en el bloqueo, le sugeriré que use un nivel de aislamiento de transacción optimizado.
REFERENCIA: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/snapshot-isolation-in-sql-server
Si el problema no está en el bloqueo de lectura / escritura, puede intentar agregar índices en su vista (la mejor opción de índices depende de la selectividad de sus datos)
fuente
IX_ListingSearchView_ForAPI
(vea el script en la pregunta).