2010-05-26 2 views
4

J'ai une importation entre 2 serveurs liés. Je dois essentiellement obtenir les données d'une jointure multiple dans une table de mon côté.Performances de la requête inter-base de données (entre serveurs liés)

La requête actuelle est quelque chose comme ceci:

select a.* 
from db1.dbo.tbl1 a 
     inner join db1.dbo.tbl2 on ... 
     inner join db1.dbo.tbl3 on ... 
     inner join db1.dbo.tbl4 on ... 
     inner join db2.dbo.myside on ... 

DB1 = serveur lié

db2 = ma propre base de données

Après celui-ci, j'utilise un insert dans + Sélectionner pour ajouter ces données dans ma table qui se trouve dans db2. (habituellement quelques centaines d'enregistrements - cette importation s'exécute une fois par minute)

Ma question est liée à la performance. Les tables sur le serveur lié (tbl1, tbl2, tbl3, tbl4) sont des tables énormes, avec des millions d'enregistrements, et ralentissent le processus d'importation. On m'a dit que, si je fais la jointure du côté "autre" (db1 - serveur lié) par exemple dans une procédure stockée, que, même si la requête semble la même, elle fonctionnerait plus vite. Est-ce correct? C'est un peu difficile à tester. Notez que la jointure contient également une table de ma base de données.

Aussi. Y a-t-il d'autres "trucs" que je pourrais utiliser pour accélérer cette course? Merci

Répondre

1

Il est correct de placer une procédure stockée sur db1 pour améliorer les performances, de cette façon moins de données doivent passer par-dessus le canal, car un lot est filtré dans les jointures.

Si les données de l'autre côté sont statiques, pourquoi ne pas les placer dans une vue matérialisée? De cette façon, vous n'avez qu'à mettre à jour les données une fois par jour au lieu de chaque fois que la requête est exécutée.

1

Les procédures stockées sont mises en cache. Par conséquent, la première fois que vous exécuterez la procédure stockée, cela prendra un certain temps. Tous les autres appels à cette procédure stockée s'exécuteront beaucoup plus rapidement. Vous pouvez voir l'impact sur les performances en incluant la statistique d'exécution dans votre SSMS. Pour améliorer les performances de jointure, assurez-vous d'avoir des index en place.

Notez que les interconnexions entre serveurs sont dangereuses car vous utilisez le réseau. Je ne suis pas sûr que vous puissiez utiliser des transactions dans ce scénario. Sinon, c'est un autre problème.

J'ai vu un scénario où la base de données temporaire n'était pas capable de faire face à une telle insertion, et le correctif consistait à utiliser un curseur. C'est beaucoup plus lent, mais plus fiable pour ce scénario.

2

Cela dépend vraiment de ce que fait réellement votre requête. Vous pouvez utiliser l'indicateur "distant" sur les jointures pour forcer la jointure à se produire sur le serveur lié. à savoir:

select a.* 
from db1.dbo.tbl1 a 
     inner remote join db1.dbo.tbl2 on ... 
     inner remote join db1.dbo.tbl3 on ... 
     inner remote join db1.dbo.tbl4 on ... 
     inner join db2.dbo.myside on ... 

(je suppose que vous avez quitté le serveur de ce qui précède et que toutes les références sont vraiment « linkedserver.db1 » « DB1. ».)

Si vous pouvez faire la plupart des travaux Avec juste des informations sur le serveur lié, vous pouvez utiliser OPENQUERY pour accélérer les choses. à savoir:

select a.* 
from OPENQUERY(db1, 'SELECT a.* from db1.dbo.tbl1 a 
     inner join db1.dbo.tbl2 on ... 
     inner join db1.dbo.tbl3 on ... 
     inner join db1.dbo.tbl4 on ... ') a 
     inner join db2.dbo.myside on ... 

Mais la meilleure façon d'accélérer peut avoir une table de commande sur le serveur lié à contrôler ce que pour revenir, mais encore une fois cela dépend de votre requête réelle, ce qu'il fait, et les autorisations vous avez sur le serveur lié.

Questions connexes