Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Problèmes de performances intermittents de la fonction SQL Server

Le comportement que vous décrivez est souvent dû à un plan de requête mal mis en cache et/ou à des statistiques obsolètes.

Cela se produit généralement lorsque vous avez un grand nombre de paramètres dans une clause WHERE, en particulier une longue liste de ceux qui sont de la forme :

(@parameter1 is NULL OR TableColumn1 = @parameter1)

Supposons que le plan de requête mis en cache expire et que la procédure soit appelée avec un ensemble de paramètres non représentatif. Le plan est ensuite mis en cache pour ce profil de données. MAIS, si le proc est plus souvent commun avec un ensemble de paramètres très différent, le plan pourrait ne pas être approprié. Ceci est souvent connu sous le nom de "reniflage de paramètres".

Il existe des moyens d'atténuer et d'éliminer ce problème, mais ils peuvent impliquer des compromis et dépendent de votre version de SQL Server. Regardez OPTIMIZE FOR et OPTIMIZE FOR UNKNOWN . SI (et c'est un gros si) le proc est appelé rarement mais doit s'exécuter aussi vite que possible, vous pouvez le marquer comme OPTION(RECOMPILE) , pour forcer une recompilation à chaque fois qu'il est appelé, MAIS ne le faites pas pour les procs fréquemment appelés OU sans enquête.

[REMARQUE :sachez qui Service pack et mise à jour cumulative (CU) votre boîte SQL Server 2008 a, car la logique de recompilation et de reniflage des paramètres fonctionne différemment dans certaines versions]

Exécutez cette requête (de Glenn Berry) pour déterminer l'état des statistiques :

-- 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);