web-dev-qa-db-fra.com

Verrouillage de table sur insertion - Comment optimiser

nous avons quelques procédures de course de longue durée dans la base de données, ce qui cause une verrouillage de table instantané sur notre table de stockage de texte principal, qui cause toutes les autres demandes de l'application Web. parce que la table est utilisée dans presque toutes les demandes).

Installer

  1. Application Web avec ASP.NET, Framework entité, SQL Server 2008R2
  2. Beaucoup de tables (table par stratégie de classe) avec attributs de données
  3. Une table ("Dbo.translations") pour des textes définis dynamiques (pour activer les traductions).
  4. Pas de clés étrangères de cette table

Pour obtenir le texte de l'objet dans la langue droite, l'ID d'objet est enregistré sur la table de traduction avec la valeur de texte.

Définition de table

Donc, le tableau de traduction ressemble à:

dbo.Translations (ID Varchar (36), Type Varchar (10), Lang Varchar (5), Valeur Varchar (MAX)))

alors que le type est défini pour chaque objet et Lang est comme "EN-GB" (non pertinent).

Indice

La table a deux index: pk_translations sur ID (clustered, non unique) UNQ_TRANSLATIONS SUR TOUT COLONNES (non cluster, unique)

Problème

La table doit gérer deux opérations: sélectionne et insertion.

La mise à jour et la suppression ne sont pas un cas d'utilisation courante.

La table contient près de 1.000.000 lignes et un indice sur ID, type, lang.

Lorsque l'application Web souhaite insérer (plusieurs) enregistrements, l'opération prend beaucoup de temps et crée une serrure de table instantanée. Cela empêche toute autre demande de cette table (peut-être même à d'autres tables, il semble donc parfois être un verrou de base de données ?!) et les amène à attendre.

Insertion

Les inserts de grandes données sont effectués de la manière suivante:

INSERT INTO Translations
   (Id, Typ, lang, value)
SELECT
   td.nId,
   td.Typ,
   td.lang,
   td.value
   FROM #tempDictionary td

Remarque: #tempprimerie est une table temporaire

Pas

Les étapes suivantes où ont été testées et n'a pas amélioré la situation:

  1. Démarrez la transaction SELECT avec lecture non engagée -> Pas de changement
  2. Étendre la plus faible de l'index à 50% pour que les enregistrements insérés puissent être sauvegardés facilement -> aucun changement

Comment puis-je savoir pourquoi le serveur SQL crée un verrou de table/dB?

3
p0wl
  1. Êtes-vous sûr à 100% que ce processus augmente vers un matal? Vous pouvez vérifier cela avec Adam Machanic's sp_whoisactive. Prenez un instantané (exécuter le PROC) pendant que le processus est en cours d'exécution (et bloquez probablement). Collectez les serrures et le plan de requête - cela vous donnera des informations nécessaires pour résoudre ce problème. Veuillez noter ce que les plumes attendent dans l'insert attendent ... S'ils attendent sur des verrous, nous avons une situation de page Split Server son problème de blocage/verrouillage

  2. Rappelez-vous que l'escalade de verrouillage se produit lorsqu'une instruction unique aboutit à 5 km sur une table ou un index. (- http://technet.microsoft.com/en-us/library/ms184286 (v = SQL.105) .aspx ) J'ai trouvé que l'utilisation de l'indice Paglock (vous prenez donc moins de serrures plus grossières ) Peut être utilisé pour éviter l'escalade en matricule.

  3. Jetez un coup d'œil au plan de requête collecté à l'étape 1. Quelle est l'estimation de la cardinalité de la ligne d'insertion (c'est-à-dire la déclaration de sélection) ... est-ce beaucoup plus grand de 5k? Si vous voulez que vous souhaitiez coder une boucle - de sorte que vous n'introduisez que 2500 lignes à la fois ...

2
JoeOBrien