Une requête comme celle ci-dessous qui est garantie de ne retourner aucune ligne, prend de 0 à 160 secondes sur l'un de nos serveurs:
select col1, col2, col3
from tab1
where 0 = 1
Il y a deux semaines, cela s'est produit six fois dans un intervalle de 48 heures. La semaine dernière, la même requête a pris ~ 0 seconde. J'ai des journaux des SQL de notre application mais je n'ai pas encore trouvé de suspects. En outre, je pensais qu'une requête de type 0/1 où 0 = 1 ne touchait jamais les pages de données, donc elle devrait être résistante aux verrous de données au niveau ligne / page / table? Le schéma n'est touché par aucun SQL (connu).
Étant donné que le problème n'est pas cohérent et que le serveur est soumis à une charge très élevée, j'aimerais comprendre la théorie derrière ce qui se passe avant d'attacher SQL profiler. D'autres requêtes s'exécutent sans problème pendant ces délais. Un problème connu dans l'application est un nombre élevé de requêtes SQL créées dynamiquement - environ 200 000 requêtes uniques de 850 000 requêtes totales (enregistrées) sur une période de 48 heures, cela peut-il provoquer des problèmes comme celui-ci?
Le serveur exécute l'édition standard de SQL Server 2005, 96 Go de RAM, des disques sur SAN et 4 processeurs / 16 cœurs. Les fichiers de base de données et les groupes de fichiers sont bien optimisés et ne devraient pas poser de problème (mais nous examinons cela séparément).
Tous les pointeurs où chercher sont grandement appréciés.
Edit: parfait! Relu la requête pour ajouter le plan d'exécution, et cela a pris 1min 35secs. Voici le plan d'exécution et la capture d'écran montrant la durée de la requête:
Edit 2: statistiques des détails de temps pour une deuxième exécution. Semble être constamment lent en ce moment, nous allons donc attacher profiler et perfmon:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 97402 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
la source
Réponses:
Il semble que même avec une
... WHERE 0 = 1
clause, il y aura toujours une exigence pour unIS
verrou shared ( ) intentionnel sur la table. Prouvons cela:Je vais commencer par créer une table de test:
Maintenant que j'ai ma table de test, en une seule session (fenêtre de requête) je vais exécuter ce qui suit pour mettre un
X
verrou exclusif ( )dbo.MyTestTable1
:Je peux vérifier le verrou exclusif en regardant le
sys.dm_tran_locks
DMV. Ensuite, dans une autre session (nouvelle fenêtre de requête), je fais exactement ce que fait votre requête:À première vue, je vois qu'il ne se termine pas. En regardant
sys.dm_exec_requests
, je vois exactement pourquoi c'est le cas:Je peux voir ici que ma
... WHERE 0 = 1
requête attend unIS
verrou pour cet objet (cet object_id se traduit pardbo.MyTestTable1
).Je ne dis nullement que la concurrence est votre problème, mais par les sons que vous en présentez les symptômes. L'exemple ci-dessus est de prouver que vous n'êtes pas exempté de verrouillage et de blocage, même avec une
WHERE
clause qui ne renverra jamais de données.Tout ce que nous pouvons faire est de deviner, donc ce que vous devez faire quand cela "prend beaucoup de temps" est de voir exactement ce que fait cette demande qui prend si longtemps. S'il attend quelque chose, voyez ce qu'il attend.
la source
En fonction de l'épaisseur et du thread exigeant vos requêtes, votre système peut simplement mettre cette requête en file d'attente. Le nombre de travailleurs par défaut (c'est-à-dire le nombre de threads SQL Server simultanés) pour votre configuration doit être d'environ 700.
Consultez sys.dm_os_schedulers et sys.dm_os_waiting_tasks pour voir si cela pourrait être un problème.
la source