Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Problemas de desempenho intermitentes da função do SQL Server


O comportamento que você está descrevendo geralmente se deve a um plano de consulta armazenado em cache incorretamente e/ou estatísticas desatualizadas.

Geralmente ocorre quando você tem um grande número de parâmetros em uma cláusula WHERE, especialmente uma longa lista daqueles que estão no formato:
(@parameter1 is NULL OR TableColumn1 = @parameter1)

Digamos, o plano de consulta em cache expira e o proc é chamado com um conjunto de parâmetros não representativo. O plano é então armazenado em cache para este perfil de dados. MAS, se o proc for mais comum com um conjunto de parâmetros muito diferente, o plano pode não ser apropriado. Isso é muitas vezes conhecido como 'sniffing de parâmetros'.

Existem maneiras de mitigar e eliminar esse problema, mas elas podem envolver compensações e depender da sua versão do SQL Server. Veja OPTIMIZE FOR e OPTIMIZE FOR UNKNOWN . SE (e é um grande se) o proc é chamado com pouca frequência, mas deve ser executado o mais rápido possível, você pode marcá-lo como OPTION(RECOMPILE) , para forçar uma recompilação cada vez que for chamado, MAS não faça isso para procs chamados com frequência OU sem investigação.

[OBSERVAÇÃO:saiba que Service pack e atualização cumulativa (CU) sua caixa do SQL Server 2008 tem, pois a lógica de recompilação e sniffing de parâmetros funciona de maneira diferente em algumas versões]

Execute esta consulta (de Glenn Berry) para determinar o estado das estatísticas:
-- When were Statistics last updated on all indexes?
SELECT o.name, i.name AS [Index Name],  
      STATS_DATE(i.[object_id], i.index_id) AS [Statistics Date], 
      s.auto_created, s.no_recompute, s.user_created, st.row_count
FROM sys.objects AS o WITH (NOLOCK)
INNER JOIN sys.indexes AS i WITH (NOLOCK)
ON o.[object_id] = i.[object_id]
INNER JOIN sys.stats AS s WITH (NOLOCK)
ON i.[object_id] = s.[object_id] 
AND i.index_id = s.stats_id
INNER JOIN sys.dm_db_partition_stats AS st WITH (NOLOCK)
ON o.[object_id] = st.[object_id]
AND i.[index_id] = st.[index_id]
WHERE o.[type] = 'U'
ORDER BY STATS_DATE(i.[object_id], i.index_id) ASC OPTION (RECOMPILE);