Comment savoir pourquoi une insertion sur une certaine table est lente?

29

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 temps de réponse en écriture IO
  • ... 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.

BradC
la source
L'extension automatique est-elle activée sur vos fichiers de données? Cela peut entraîner des problèmes de performances avec la configuration par défaut.
Larry Coleman
Parlons-nous d'utiliser un profileur? msdn.microsoft.com/en-us/library/ms187929.aspx
Incognito
@Larry: Les fichiers de données ont un espace libre important, donc je ne pense pas que la croissance des fichiers de données soit un problème. Bon à ajouter à la liste des "choses à vérifier".
BradC
@ user210: Le profilage de l'achèvement de l'instruction me montre que cela a pris 90 secondes, il ne me dit pas POURQUOI. À moins qu'il n'y ait d'autres événements qui, à votre avis, seraient plus révélateurs.
BradC

Réponses:

10

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 les statistiques d'E / S pour voir combien d'E / S les recherches FK nécessitent.

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

Commençons ici et voyons où nous allons.

mrdenny
la source
2
La réduction de la taille du lot aide (1000 enregistrements prennent environ 25 secondes). C'est probablement notre "solution de contournement" actuelle. Je vais voir si je peux déterminer les statistiques d'E / S et les attentes (le travail est exécuté à la demande par le client lorsqu'il a un fichier à traiter, donc je ne peux pas toujours prédire quand le travail sera réellement exécuté).
BradC
7

Brad,

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

SQLRockstar
la source
6

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. Ajouter à eux colonne rowcounts pour voir exactement le nombre de lignes dans le lot. Filtrez les résultats pour ne voir que votre requête.
  • enfin collecter le compteur d' espérance de vie de page à partir de 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.
yrushka
la source
5

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 d'E / S et d'UC pour ce qui coûte le plus cher dans la requête (s'agit-il de l'analyse de la table sur votre table temporaire par rapport au type à insérer dans votre clé en cluster, etc ...)

Andrew Bickerton
la source