web-dev-qa-db-fra.com

Rejoindre des tables dans deux bases de données rend la requête lente? vaut mieux partitionner db?

J'ai un table1 Dans db1 Et table2 Dans db2 Sur SQL Server 2008 R2.

Si je fais une requête de sélection joignant les deux tables, il est vraiment lent d'obtenir les résultats.

Une requête simple comme

SELECT * 
FROM db1.dbo.table1 t1 
LEFT JOIN db2.dbo.table2 t2 ON t1.k1 = t2.k2

est VRAIMENT lent parfois.

Je ne sais pas si cela est commun à SQL Server et "doit être comme une règle" pour "ne pas joindre deux tables provenant de bases de données différentes".

Dans ce cas ... J'ajoute à cette question que j'ai une de ces données binaires db stockées sur un champ et j'aime me séparer de la db principale pour ne pas augmenter la taille de la table principale ... il est préférable de partitionner une db pour cela ?

J'ai testé avec deux tables simples et rejoindre ces deux tables est toujours lent.

Merci d'avance pour votre aide.

.. Mise à jour quelques années plus tard ... 24-09-18

assurez-vous que les champs que vous joignez sont de même type, taille et classement.

Exemple: une propriété est varchar (255) et une autre varchar (20) ... cela peut être un problème car le moteur doit convertir un type en un autre (une conversion implicite se produit) et bien que parfois il s'exécute plus rapidement ... si un une réindexation ou un changement dans la base de données se produit, vous pouvez voir qu'à un moment donné, le démarrage de la requête a pris beaucoup plus de temps pour se terminer ...

Si vous ne pouvez pas modifier le type de champ pour qu'il corresponde dans l'une des bases de données/tables, essayez de faire un cast explicite pour voir si cela améliore la vitesse de requête. utilisez cast(fieldname as type(size)) = fieldName2)

9
FabianSilva

Vous avez ici un tas de questions différentes, alors décomposons-les individuellement.

Q: Si je joins deux tables dans la même base de données avec la requête ci-dessus, pourquoi est-ce lent?

R: Pour commencer, vous n'utilisez pas de clause WHERE, donc SQL Server doit créer l'ensemble de résultats complet, fusionnant les deux tables ensemble. Si vous n'avez besoin que d'un sous-ensemble de données, envisagez d'utiliser une clause WHERE pour obtenir uniquement les données dont vous avez besoin.

Une fois que vous avez fait cela, notez que vous utilisez une jointure extérieure gauche. Cela indique à SQL Server "tous les enregistrements table1 n'auront pas les enregistrements correspondants dans table2". C'est tout à fait correct si c'est vrai - mais si vous savez que tous les enregistrements t1 auront au moins un enregistrement t2, utilisez plutôt un INNER JOIN.

Ensuite, l'indexation commence à entrer en jeu - selon la largeur des tables et le nombre de champs, vous souhaiterez peut-être ajouter des index sur les champs que vous utilisez pour la jointure. Pour obtenir de bons conseils à ce sujet, il est préférable de publier le plan d'exécution réel avec lequel vous travaillez.

Q: Si les tables se trouvent dans différentes bases de données sur le même serveur SQL, cela change-t-il quelque chose?

R: Non. Il y a des problèmes intéressants autour de choses comme les niveaux d'isolement par défaut dans différentes bases de données, mais pour la plupart, vos requêtes devraient produire les mêmes plans et vitesses d'exécution.

Q: Dois-je utiliser le partitionnement de table pour accélérer les choses?

R: Vous avez mentionné le partitionnement de la base de données, mais il n'y a rien de tel dans SQL Server - je suppose que vous vouliez dire le partitionnement de table. De manière générale, non, je ne voudrais pas passer aux modifications de conception de base de données afin d'accélérer une jointure. Commencez par les bases - comprendre les plans d'exécution de SQL Server - et apportez uniquement des modifications à la conception de la base de données pour résoudre les problèmes que vous ne pouvez pas résoudre avec des choses comme les index.

23
Brent Ozar