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:
- Divisez les 20 jointures en 4 jointures sur 5 tables. Les performances des requêtes restent cependant faibles.
- Placez des index sur les colonnes de clé étrangère. Pas de diminution significative du temps.
- 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.
- 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
- Quelles sont les raisons possibles de l'insertion lente de la table?
- Comment identifier ce goulot d'étranglement sans le plan d'exécution?
- Quelles mesures puis-je prendre pour réduire le coût de l'insert de table?
la source
Réponses:
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 .
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:
Utilisez le commutateur de partition pour déplacer les données. C'est de loin la meilleure solution. Préparez les données de transfert dans une table de transfert distincte, puis basculez cette table de transfert dans la table DW. Lisez Transfert de données de manière efficace à l'aide de la commutation de partition .
Assurez-vous que l'INSERT est enregistré de façon minimale. Lisez les opérations pouvant être enregistrées de manière minimale et les conditions préalables à une journalisation minimale . Même si vous utilisez des opérations de commutateur de partition, il vaut toujours la peine de s'assurer que la construction de la table intermédiaire est journalisée de manière minimale.
Assurez-vous que votre sous-système d'E / S est capable de conduire une charge rapide. Lisez Présentation des SSD .
la source
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.
Essayez donc ces deux stratégies et voyez comment cela fonctionne pour vous.
la source
Essayez d'utiliser le partitionnement et le partitionnement de table sur la base de données, cela pourrait aider à obtenir les performances.
la source