Optimisation des performances d'insertion de table de serveur SQL

8

Réglage

Dans un datawarehouse, je joins une table de faits à 20 dimensions. La table de faits comprend 32 millions de lignes et 30 colonnes. Il s'agit d'une table de transfert temporaire, je n'ai donc pas à traiter avec d'autres utilisateurs lisant ou écrivant sur la table. Je sélectionne 10 colonnes de la table de base et 20 colonnes des dimensions respectives. Les tableaux de dimensions sont petits (entre 3 et 15 000 lignes). Les champs sur lesquels sont joints sont à la fois des entiers et des nvarchars. J'utilise une instruction SELECT ... INTO. Il n'y a pas d'index sur les tables.

La vitesse d'exécution de cette requête est trop lente pour être utile.

Solutions éprouvées

Parce que la requête prend trop de temps à traiter, j'ai essayé les solutions suivantes:

  1. Divisez les 20 jointures en 4 jointures sur 5 tables. Les performances des requêtes restent cependant faibles.
  2. Placez des index sur les colonnes de clé étrangère. Pas de diminution significative du temps.
  3. Assurez-vous que les champs de la condition de jointure sont des entiers. J'ai remarqué une augmentation des performances de 25%. Pas tout à fait ce que je recherche.
  4. Utilisez une instruction d'insertion dans au lieu de sélectionner dans. Pire performance en raison de la croissance du fichier journal bien que la base de données soit en mode de récupération simple.

Ces résultats m'ont amené à inclure le plan d'exécution réel qui montre que 89% des coûts se trouvent dans l' encart du tableau . Les autres coûts sont 8% d'analyse de table sur la table de faits et 2% sur la correspondance de hachage pour les jointures internes.

Des questions

  1. Quelles sont les raisons possibles de l'insertion lente de la table?
  2. Comment identifier ce goulot d'étranglement sans le plan d'exécution?
  3. Quelles mesures puis-je prendre pour réduire le coût de l'insert de table?
Drizzt
la source
SELECT INTO est la méthode d'insertion DML la plus rapide qui soit. Quel débit obtenez-vous en lignes / s et en Mo / s? Peut-être est-il simplement proche du maximum attendu. De quelle version de serveur s'agit-il?
usr
Les pourcentages dans le plan réel sont des estimations et non les pourcentages réels. L'utilisation de "statistiques io" pourrait révéler quelque chose d'important.
James Z

Réponses:

12

Quelles sont les raisons possibles de l'insertion lente de la table? Comment identifier ce goulot d'étranglement sans le plan d'exécution?

Lisez Comment analyser les performances de SQL Server , en particulier la partie sur l' analyse des temps d'attente pour l'exécution de chaque requête .

Quelles mesures puis-je prendre pour réduire le coût de l'insert de table?

Cela dépendrait largement du résultat de l'analyse des performances. Tout d'abord, assurez-vous que la partie SELECT est aussi rapide que possible. En supposant que ce problème est l'insertion entièrement journalisée à thread unique, certaines solutions sont les suivantes:

Remus Rusanu
la source
Vérifiez également la fragmentation interne et externe si de nombreuses lignes étalées sont d'abord supprimées du tableau.
Ian Ringrose
1

Voici mon expérience et pourrait aider quelqu'un d'autre là-bas.

Nous essayions de transférer certaines données d'une base de données à une autre en effectuant également des transformations. En testant la transformation, nous faisions beaucoup d'inserts, corrigions les choses en cours de route, puis supprimions afin de tester à nouveau l'insert. Cependant, après quelques insertions et tronques, nos requêtes ont commencé à fonctionner lentement et une insertion simple a commencé à prendre jusqu'à 9 minutes alors qu'elle fonctionnait auparavant pendant environ 3 minutes.

  1. Eh bien, nous avons commencé par chercher à optimiser les SELECT en premier. Au lieu de sous-requêtes, nous avons utilisé #tempTables. Bien que cela ait accéléré un peu les choses, ce n'était toujours pas satisfaisant.
  2. Ce qui a fait toute la différence, c'est la reconstruction de l'index et une mise à jour des statistiques sur la base de données de destination et cela a amené l'insertion en environ 2 minutes.

Essayez donc ces deux stratégies et voyez comment cela fonctionne pour vous.

Kleidi
la source
0

Essayez d'utiliser le partitionnement et le partitionnement de table sur la base de données, cela pourrait aider à obtenir les performances.

vishal walujwar
la source