web-dev-qa-db-fra.com

Comment puis-je savoir POURQUOI une insertion sur une certaine table est lente?

Je sais qu'un INSERT sur une table SQL peut être lent pour plusieurs raisons:

  • Existence de INSERT TRIGGER sur la table
  • Beaucoup de contraintes imposées qui doivent être vérifiées (généralement des clés étrangères)
  • La page se divise dans l'index cluster lorsqu'une ligne est insérée au milieu du tableau
  • Mise à jour de tous les index non cluster liés
  • Blocage d'une autre activité sur la table
  • Mauvais IO temps de réponse d'écriture
  • ... quelque chose que j'ai manqué?

Comment savoir qui est responsable dans mon cas spécifique? Comment puis-je mesurer l'impact des fractionnements de page par rapport aux mises à jour d'index non clusterisées par rapport à tout le reste?

J'ai un proc stocké qui insère environ 10 000 lignes à la fois (à partir d'une table temporaire), ce qui prend environ 90 secondes par 10 000 lignes. C'est trop lent, car cela provoque la temporisation d'autres spids.

J'ai examiné le plan d'exécution et je vois la tâche INSERT CLUSTERED INDEX et toutes les INDEX SEEKS des recherches FK, mais cela ne me dit toujours pas avec certitude pourquoi cela prend si longtemps. Pas de déclencheurs, mais la table a une poignée de FKeys (qui semblent être correctement indexés).

Il s'agit d'une base de données SQL 2000.

30
BradC

Certaines choses que vous pouvez regarder ...

Réduisez la taille du lot de 10000 à quelque chose de plus petit, comme 2000 ou 1000 (vous n'avez pas dit la taille de votre ligne).

Essayez d'activer IO Statistiques pour voir combien IO les recherches FK prennent).

Quelle est l'attente causée par l'insertion (master.dbo.sysprocesses)?

Commençons ici et voyons où nous allons.

10
mrdenny

Brad,

Vous devez examiner les statistiques d'attente de votre requête. Avec SQL 2000, vous pouvez utiliser la syntaxe DBCC SQLPERF ("statistiques d'attente") pour obtenir ces détails.

7
SQLRockstar

Je peux dire ce que je recherche lors de l'analyse des performances d'une requête. Peut-être que ça aide.

  • analyser le plan d'exécution des requêtes et vérifier les analyses d'index, les analyses de table, l'utilisation des fonctions convert_implicit pour les types de données sql, le parallélisme.
  • exécutez la requête avec SET STATISTICS IO ON et SET STATISTICS TIME ON pour voir le temps d'exécution et lire/écrire io pour chaque insert.
  • consultez le temps d'attente de sysprocesses pour votre session spid.
  • exécutez le profileur et sélectionnez un modèle standard. sélectionnez ce qui suit: Statistiques de performances (si répétées, votre plan est compilé plusieurs fois - pas bon), RPC: terminé, SQL: terminé par lots et SQL: démarrage par lots. Ajoutez-y la colonne rowcounts pour voir exactement le nombre de lignes du lot. Filtrez les résultats pour ne voir que votre requête.
  • enfin collecter Page Life Expectancy counter from windows perfmon et s'il est inférieur à 300 (5 min) alors le SQL a une mémoire faible. Collectez également les compteurs de disque: longueur de la file d'attente du disque, heure du disque (votre lecteur de fichiers de données), heure du disque (votre lecteur de fichiers journaux) pour voir s'il y a une pression sur les disques.
6
yrushka

Essayez d'utiliser:

SET STATISTICS IO ON

et

SET STATISTICS PROFILE ON

STATISTIQUES IO

Peut être utile pour vous dire quelles tables il effectue le plus d'analyses de table, de lectures logiques et de lectures physiques (j'utilise ces trois pour se concentrer sur la partie du plan de requête qui nécessite le plus de réglages)

PROFIL STATISTIQUE

Renvoie principalement le plan de requête dans un format tabulaire, vous pouvez ensuite consulter les colonnes IO et CPU pour ce qui coûte le plus cher dans la requête (est-ce l'analyse de la table sur votre table temporaire vs le type qu'il fait pour insérer dans votre clé en cluster, etc ...)

5
Andrew Bickerton