J'ai créé une session d'événements étendue dans laquelle je voulais voir toutes les questions à l'aide de Nolock Astuce. J'ai décidé de l'utiliser à la place de la trace SQL afin de minimiser l'impact possible des performances. La session a été créée comme avec la déclaration suivante:
CREATE EVENT SESSION [SCOMDB_debug] ON SERVER
ADD EVENT sqlserver.deprecation_announcement(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)),
ADD EVENT sqlserver.rpc_completed(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.rpc_starting(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sp_statement_completed(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sp_statement_starting(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sql_batch_completed(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sql_batch_starting(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sql_statement_completed(
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%')))
ADD TARGET package0.event_file(SET filename=N'M:\MSSQL11.SCOMDB\MSSQL\Log\SCOMDB_debug.xel',max_file_size=(500))
WITH (MAX_MEMORY=40960 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO
Le résultat était que l'instance de base de données (utilisée pour les bases de données SCOM) est devenue très lente et que l'application était presque inutilisable.
Les statistiques attendues étaient pleines de sos_scheduler_yield et de Preemptif_xe_dispatcher et je pouvais voir de nombreuses questions de course à pied dans SYS.DM_EXEC_Requests en attente de la majeure partie de la CPU.
Est-ce qu'il est expecté Bahaviour? Je peux imaginer que l'opérateur [similaire_i_sql_unicode_string] peut être assez performant, mais je m'attendrais toujours à bien mieux performance.
Y a-t-il un autre filtre dans EX EVENTS qui pourraient être utilisés pour attraper des requêtes contenant '0text '?
Je dirais que vous n'avez pas besoin de tous les événements start
, juste le completed
. Je ne vois pas que vous capturez des données uniquement pour la base de données SCOM. Les événements prolongés peuvent provoquer une surcharge, juste près de ce que SQL Server Traces Selon ce que vous essayez de capturer.
Vous capturez essentiellement chaque requête qui entre sur le serveur et que vous lui indiquez d'attendre afin que vous puissiez d'abord vérifier le texte de la requête, puis saisir des informations via la session d'événement étendue, puis la laisser terminer.
De plus, l'activité constante SCOM a, en fonction de la configuration de l'environnement, il est susceptible d'avoir une performance extrême touchée avec des événements de trace ou d'événements prolongés. Je suggérerais de regarder le cache de plan pour ces types de questions initialement. Cependant, vous pouvez essayer d'ajouter davantage de filtres à votre session, ce qui n'atteignez que un échantillon de données à partir de sessions actives, puis ne capturant ainsi que des données pour la base de données particulière. Cela ressemblerait à quelque chose comme ça à travers l'interface graphique:
Ou code votre clause WHERE
_ apparaît quelque chose comme:
WHERE ((([package0].[divides_by_uint64]([sqlserver].[session_id],(5)))
AND ([package0].[greater_than_uint64]([sqlserver].[database_id],(4))))
AND ([package0].[equal_boolean]([sqlserver].[is_system],(0)))))
Cela capturerait, je pense que 20% des sessions actives de cette base de données à tout moment. Cependant, si vous voulez tous les événements, vous devrez subir la surcharge de cette action.
Avec cela étant un produit Microsoft, je ne serais pas à préoccuper des requêtes qu'il produisent. S'il s'agit de problèmes de performance, vous devez suivre les directives Microsoft pour le produit ou consulter le support Microsoft.