Utilisation de SPID dans les tables de base de données (au lieu de la variable de table)


8

Base de données transactionnelle utilisée pour réserver des choses ...

Notre fournisseur a été invité à remplacer #temptables par @tablevariables (en raison de verrous de compilation importants), mais à la place, il a été remplacé par une table réelle qui ajoute SPID en tant que colonne pour garantir que la procédure stockée n'agit que sur les lignes applicables.

Voyez-vous un risque dans cette méthode de fonctionnement? Avant que toutes les transactions ne soient isolées au sein de leur propre transaction ... Je craignais que nous finissions par verrouiller cette table un tas, mais leur opinion est que SQL utilise le verrouillage au niveau des lignes et cela ne créera pas plus de verrous.

Version de SQL Server: 2016 Enterprise - 13.0.5216.0


CREATE TABLE dbo.qryTransactions (
    ID int IDENTITY (0,1) NOT NULL CONSTRAINT pk_qryTransactions PRIMARY KEY CLUSTERED,
    spid int NOT NULL,
    OrderID int,
    ItemID int,
    TimeTransactionStart datetime,
    TimeTransactionEnd datetime,
...other fields
    )

CREATE INDEX idx_qryTransactions_spidID ON qryTransactions (spid, ID) INCLUDE (ItemID, OrderID, TimeTransactionStart, TimeTransactionEnd)

1
Ça dépend. Combien de sessions utilisent simultanément la table, à quel point ces sessions sont-elles actives, combien d'enregistrements se trouvent dans la table, les enregistrements de cette nouvelle table sont-ils purgés ou restent-ils, etc.? 5 séances, ce n'est pas grave. 500 sessions, les chances sont bonnes que vous allez rencontrer des blocages que vous ne verriez pas avec des tables / variables temporaires locales à chaque session.
John Eisbrener

Quelle version de SQL Server utilisez-vous?
Anthony Genovese

2016 Enterprise - 13.0.5216.0
outjet

Les enregistrements par session atteignant la table seront de 1 à 50 ... ils seront purgés, de sorte que la table elle-même n'obtiendra probablement pas plus de 1 000 lignes à la fois ... sessions simultanées probablement autour de 50 ....
outjet

1
Si vous êtes obligé de suivre ce chemin (veuillez essayer de l'éviter), je réfléchirais sérieusement au partitionnement de la valeur spid, en m'assurant que l'escalade de verrous sur la table est définie sur AUTO. Ensuite, au moins l'effacement des données d'un spid spécifique pourrait être effectué dans une opération de commutation et de tronquage.
Jonathan Fite

Réponses:


5

Un peu plus décousu que ce qui peut tenir dans un bloc de commentaires ... et je veux mettre en évidence un commentaire que l'OP a fait en réponse à la réponse de Ray:

  • proc parent (Common_InsertOrders_1) crée une table temporaire
  • un proc enfant (InsertOrders) interroge la table temporaire
  • des verrous de compilation sont vus pour le processus enfant (InsertOrders)

Partir sur une légère tangente pendant une minute ... sur ce qui se passerait avec ce scénario est Sybase ASE ...

  • chaque table temporaire obtient un identifiant d'objet unique (bien sûr, l'identifiant d'objet pourrait être réutilisé à un moment donné, mais cela est rare et ne se produira certainement pas pour les sessions simultanées)
  • Sybase ASE forcera normalement une recompilation à chaque exécution du proc enfant en raison du changement d'ID d'objet pour la table temporaire
  • Sybase ASE forcera également une recompilation du proc enfant s'il voit que la structure de la table temporaire a changé (par exemple, un nombre différent de colonnes, différents noms de colonne / types de données / nullabilité) entre les appels de proc stockés
  • les versions plus récentes de Sybase ASE ont une configuration qui (effectivement) indique au compilateur d'ignorer les modifications des identifiants des objets de la table temporaire, éliminant ainsi la recompilation du proc enfant (REMARQUE: les recompilations se produiront toujours si la structure de la table change)

Retour au problème de l'OP (les verrous de compilation sur le proc enfant) ...

  • y a-t-il une chance que certains vestiges du comportement Sybase ASE puissent encore résider dans SQL Server (à partir du moment où les deux produits étaient des pois dans un pod)?
  • Existe-t-il des configurations SQL Server qui pourraient réduire (éliminer?) les recompilations du processus enfant (si elles sont dues à des changements d'ID d'objet)?
  • l'OP peut-il vérifier que le proc parent crée la table temporaire avec la même structure / DDL exacte à chaque fois?

Quant à l'idée d'utiliser une seule table permanente avec @@ SPID pour différencier les lignes entre les sessions ... été là, vu que ... beurk ; problèmes récurrents:

  • comment / quand nettoyer les lignes orphelines
  • la réutilisation du @@ SPID par le moteur de base de données pourrait entraîner des problèmes de précision des données si des données orphelines existent (ou pendant le nettoyage des données orphelines, par exemple, supprimer où @@ SPID = 10 mais il y a une session nouvelle / actuelle / active avec @ @ SPID = 10 => le nettoyage supprime trop de données)
  • possibilité d'escalade des verrous des verrous de ligne aux verrous de page / table
  • si la table a des index, alors potentiel (b) de verrouillage lors de la mise à jour des index
  • en fonction de la base de données dans laquelle se trouve la table, vous pourriez envisager beaucoup plus d'activité pour écrire sur le périphérique de journalisation (dans Sybase ASE, il est possible de désactiver efficacement la journalisation dans tempdb)
  • même les verrous (exclusifs) au niveau de la ligne peuvent bloquer d'autres sessions (selon le niveau d'isolement et si une session peut ou non passer / ignorer lesdits verrous exclusifs)

Je voudrais revenir en arrière et (re) enquêter sur le problème racine (verrous de recompilation sur le proc enfant) et voir s'il existe un moyen de réduire (éliminer?) Lesdits verrous de compilation. [Malheureusement, ma connaissance de SQL Server sur ces problèmes est ... NULL ... donc je serais intéressé par les commentaires de certains experts du compilateur SQL Server.]


1
Je suis d'accord, je pense que plus de temps doit être consacré à enquêter sur les verrous de compilation. Cela a quelques points à étudier. support.microsoft.com/en-us/help/263889/…
Jonathan Fite

8

Il me semble utiliser des éléments @@SPIDsimilaires qui posent problème.

Les ID de session sont réutilisés fréquemment; dès qu'une connexion utilisateur se déconnecte, cet ID de session est disponible pour être réutilisé et est susceptible d'être utilisé par la prochaine session tentant de se connecter.

Pour le faire fonctionner au moins de manière semi-fiable, vous auriez besoin d'un déclencheur de connexion qui purge les lignes précédentes de la table avec le même @@SPID. Si vous faites cela, vous verrez probablement beaucoup de verrouillage sur la table en utilisant la @@SPIDcolonne.

SQL Server utilise en effet le verrouillage de ligne, mais il utilise également le verrouillage de page et le verrouillage de table. Bien sûr, vous pourrez peut-être atténuer cela via une bonne indexation, mais cela ressemble toujours à un anti-modèle pour moi.

Si la procédure stockée est la seule méthode utilisée pour accéder aux tables affectées, vous pouvez rechercher à l'aide d'un verrou d'application, via sp_getapplockpour sérialiser essentiellement l'accès aux parties concernées. Les documents pour sp_getapplock sont ici . Erik Darling a un article intéressant à ce sujet ici .


4

Oui, je vois des risques. Il est naïf de compter sur SQL en utilisant le verrouillage de ligne. Par exemple, je suis presque sûr que les insertions et les suppressions utiliseront au moins les verrous de page. Le moteur SQL choisit le type de verrou en fonction de plusieurs facteurs et aucun de ces facteurs n'inclut "leur opinion". Les solutions générales comme le changement de tables temporaires en variables de table sont généralement aussi de mauvaises idées. Les variables de tableau sont très utiles dans certaines situations, mais elles présentent des limitations et des problèmes de performances. Je préfère les tables temporaires dans la plupart des cas. Particulièrement lorsque le tableau contiendra plus de quelques dizaines de lignes. Je demanderais au vendeur d'expliquer pourquoi le système a connu des «verrous de compilation lourds» et comment cela a dégradé les performances. Rappelez-vous, chaque fois que vous regardez, vous trouverez des "serrures lourdes" en quelque sorte. Cela ne signifie pas nécessairement que les serrures sont un problème. Max ' Les commentaires de @@ SPID sont également importants. De plus, le modèle de transaction et le traitement des erreurs pourraient être de gros problèmes. Si votre système rencontre des blocages ou des problèmes de qualité des données d'entrée, le traitement d'erreur standard peut entraîner la fermeture de la session sans que la table qryTransactions soit correctement réinitialisée. IMO la mauvaise approche de solution au problème d'origine.


Merci pour la réponse - à vos points: nos traces montrent que LCK lourd attend un verrou de compilation sur les procédures stockées InsertOrders. Il existe une procédure parent Common_InsertOrders_1 qui déclare la table temporaire #qryTransactions, puis la procédure imbriquée InsertOrders_2 interroge la table temporaire. En outre, nous avons appris qu'il y a également une recompilation fréquente car après 6 modifications d'une table temporaire vide, toute procédure stockée référençant cette table temporaire devra être recompilée
outjet

Il existe de nombreuses raisons pour lesquelles une procédure ou une instruction sera recompilée. MarkP en a mentionné un certain nombre qui s'appliquent à SyBase et je suis sûr que SQL Server est similaire. Le nombre de lignes de la table temporaire est un bon exemple et la recompilation n'est pas nécessairement une mauvaise chose. Les statistiques de table peuvent modifier considérablement le plan de requête optimal et une recompilation est nécessaire pour le déterminer. Mais je veux réitérer. Il y aura TOUJOURS un verrou supérieur et cela ne signifie pas que le verrou est un problème. Sauf si vous voyez d'autres preuves d'un problème de performances, ne vous en faites pas.
Ray
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.