J'ai un environnement avec ~ 100 bases de données, tous avec le même schéma. Il existe une procédure stockée sur chaque base de données qui crée une table #Temp et le dépose et fonctionne très souvent (toutes les 30 secondes ou par utilisateur, et il y a 1000 utilisateurs). Cela fait beaucoup plus que ceci: nous chargons potentiellement des milliers de lignes dans cette table TEMP et vaporisent simplement la totalité de la chose, il s'agit d'un groupe de données.
Étant donné que toutes les bases de données créent la même table Temp, sont-elles toutes en compétition les unes avec les autres? Ou chaque base de données obtient-elle sa propre version de la table TEMP dans TEMPDB?
Il semble qu'ils aient des conditions de discorde parce que je vois une grande quantité de PAGE_LATCH
attend, tout sur la même page de TEMPDB (2:3:1041580
), qui n'est pas une page GAM, SGAM ou PFS, et 90% des attentes semblent provenir de cette même procédure stockée dans toutes les bases de données. Ces attentes sont 90% des attentes globales sur le serveur et causent le blocage.
J'ai fait un DBCC PAGE
, et il semble être sysobjvalues
(de l'objet_id 60 dans l'en-tête). L'Iran:
SELECT OBJECT_Name(object_ID), *
FROM sys.dm_db_database_page_allocations(2,60,NULL,NULL,'DETAILED')
Je reçois 153 rangées, je ne sais pas exactement ce que je regarde ici. On dirait que c'est IN_ROW_DATA
et LOB_DATA
dans allocation_unit_type_desc
.
J'ai 8 fichiers TEMPDB sur un volume séparé des autres fichiers. J'ai 16 cœurs mais ma compréhension est que, puisque ce n'est pas une page d'allocation, cela pourrait ne pas aider à augmenter le nombre de fichiers. Utilisation de SQL Server 2017 Enterprise.
J'ai l'impression que le meilleur pari est de simplement dire aux développeurs de supprimer la table Temp ici, mais cela nécessitera de retravailler la logique et de prendre un certain temps. Y a-t-il autre chose que je puisse faire pour éviter ces loquets de page pendant que j'attends le devis de développement?
TEMPDB est une ressource partagée, donc dans une certaine mesure, oui, toutes les sessions sont en concurrence pour cette ressource. Mais cela n'a rien à voir avec le nom de la table étant le même que SQL Server ajoute un ensemble unique de caractères à la fin de chaque nom de table temporaire local. Il faudrait faire avec la création/déposer des tables temporaires en général et des opérations DML contre ces tableaux (que et si vous utilisez l'isolement de l'instantané, il utilise tempdb
pour la version de la version et les déclencheurs utilisent tempdb
Pour les inserted
et deleted
tables).
Je ne crois pas que ce soit la table Temp elle-même qui est la question car "une fois toutes les 30 secondes" n'est pas aussi fréquente que vous pourriez penser. J'ai travaillé sur des systèmes avec des milliers de transactions par seconde et beaucoup d'utilisation de TEMP DB.
Je regarderais:
Qu'est-ce qui se fait avec cette table Temp? Combien de données est chargée dedans? Y a-t-il beaucoup de mises à jour? S'il y a beaucoup de lignes, l'ajout peut-être qu'un indice pourrait aider?
La table TEMP est-elle créée dans une transaction? Soit dans une transaction explicite (c'est-à-dire = BEGIN TRAN
) Ou peut-être dans une gâchette? Si oui, alors j'ai vu que le scénario provoque le blocage. Il est préférable de créer la table Temp en dehors de la transaction et une fois créé, puis effectuez des relevés DML dans la transaction.
De plus, depuis que vous êtes sur SQL Server 2017 Enterprise, vous pourriez peut-être examiner en utilisant en mémoire OLTP pour échanger la table TEMP basée sur un disque. Je crois que cela créerait un type de table défini par l'utilisateur en mémoire, puis crée une variable de table à partir de cette UDTT.