Question

Un collègue m'a demandé d'examiner l'indexation de certaines tables car sa requête était très longue. Plus d'une heure.

select count(1)
from databaseA.dbo.table1
inner join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)

Notez les différentes bases de données. Ceci était exécuté à partir de DatabaseB

Les tableaux 1 et 2 contiennent plus de 2 millions d’enregistrements. Table3 avait une douzaine d'enregistrements ou plus.

J'ai consulté le plan de requête et l'optimiseur a décidé de faire une recherche d'index de boucle imbriquée dans les tableaux 1 et 2 avec Table3 comme table de base!

Ma première hypothèse était que les statistiques étaient gravement perturbées dans Tables1 & amp; 2 mais avant de mettre à jour les statistiques, j'ai essayé d'ajouter un indice de jointure:

select count(1)
from databaseA.dbo.table1
inner HASH join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)

Résultats renvoyés dans les 15 secondes.

Comme je n'avais que peu de temps, je lui ai renvoyé les résultats, mais je crains que cela ne crée des problèmes plus tard.

Dois-je revenir sur le problème des statistiques pour le résoudre de cette façon? Le plan de requête incorrect pourrait-il provenir de la jointure à partir de bases de données distinctes?

Quelqu'un peut-il me proposer des idées basées sur votre expérience?

Était-ce utile?

La solution

Je soupçonne d’abord les statistiques.

Comme vous le savez sans doute, les jonctions doivent être évitées dans 99% des cas et utilisées uniquement lorsque vous avez la preuve qu'elles sont absolument indispensables.

Autres conseils

Vérifiez d'abord les statistiques et l'indexation sur la table. Les indices peuvent causer des problèmes. Si les données dans les tables changent, l’optimiseur ne pourra pas choisir un plan plus efficace car vous l’avez forcé à toujours utiliser un hachage.

Une boucle imbriquée ne serait-elle pas la plus appropriée? Prenez les 12 enregistrements du tableau 3, les 12 enregistrements du tableau 1, les 12 enregistrements du tableau 2.

Sinon, votre jointure de hachage appliquera également l'ordre - ce qui signifie que vous devez hacher 1 million d'enregistrements des tableaux 1 et 2, puis rejoindre les 12 enregistrements du tableau 3.

Je regarderais les statistiques pour les deux plans - et je soupçonnerais que la jointure de boucle est en réalité plus efficace, mais a été bloquée ou votre jointure de hachage tirait parti des données mises en cache.

Mais - ouais - en général, les alliances sont un dernier recours.

Une requête à exécution lente impliquant des serveurs liés peut concerner le classement. Voir ici pour quelques informations: http://blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collation-compatibility.aspx Le signe de jointure de hachage force l'ordre de tri, ce qui explique le gain de performances.

Voici comment définir les options:

EXEC master.dbo.sp_serveroption 
    @server=N'databaseA', 
    @optname=N'collation compatible', 
    @optvalue=N'true'

EXEC master.dbo.sp_serveroption 
    @server=N'databaseA', 
    @optname=N'use remote collation', 
    @optvalue=N'false'

-Edoode

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top