La clé étrangère améliore-t-elle les performances des requêtes?

Supposons que j'ai 2 tables, Products et ProductCategories. Les deux tables ont une relation sur CategoryId. Et c'est la requête.

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;

Lorsque je crée un plan d'exécution, table ProductCategories effectue la recherche d'index de cluster, qui est en attente. Mais pour les produits de table, il effectue une analyse d'index de cluster, ce qui me fait douter. Pourquoi FK n'aide pas à améliorer les performances des requêtes?

Je dois donc créer un index sur les produits.CategoryId. Lorsque je crée à nouveau un plan d'exécution, les deux tables effectuer la recherche d'index. Et le coût estimé du sous-arbre est réduit beaucoup.

Mes questions sont:

  1. À côté de FK aide sur la contrainte de relation, a-t-il une autre utilité? Améliore-t-il les performances des requêtes?

  2. Dois-je créer un index sur toutes les colonnes FK (produits aimés.CategoryId) dans tous les tableaux?

127
demandé sur simhumileco 2009-02-03 17:03:27

9 réponses

Les clés étrangères sont un outil d'intégrité référentielle, pas un outil de performance. Au moins dans SQL Server, la création D'un FK ne crée pas d'index associé, et vous devez créer des index sur tous les champs FK pour améliorer les temps de recherche.

166
répondu cmsjr 2012-03-16 08:35:05

Les clés étrangères peuvent améliorer (et nuire) les performances

  1. Comme indiqué ici: clés Étrangères de booster les performances

  2. Vous devez toujours créer des index sur les colonnes FK pour réduire les recherches. SQL Server ne le fait pas automatiquement.

Modifier

Comme le lien semble maintenant mort (bravo à Chris pour avoir remarqué) , ce qui suit montre pourquoi les clés étrangères peuvent améliorer (et nuire) les performances.

Peut Étranger clé améliorer les performances

Contrainte de clé étrangère améliorer les performances au moment de la lecture données mais en même temps il ralentit la performance au moment de insertion / modification / suppression de données.

En cas de lecture de la requête, l'optimiseur peut utiliser des contraintes de clé étrangère pour créez des plans de requête plus efficaces en tant que clé étrangère les contraintes sont des règles pré-déclarées. Cela implique généralement de sauter une partie du plan de requête car par exemple le l'optimiseur peut voir qu'en raison d'une contrainte de clé étrangère, il est inutile d'exécuter cette partie particulière du plan.

51
répondu Lieven Keersmaekers 2013-06-05 12:02:56

Une clé étrangère est un concept de SGBD pour assurer l'intégrité de la base de données.

Toute incidence sur les performances / amélioration sera spécifique à la technologie de base de données utilisée et sera secondaire à l'objectif d'une clé étrangère.

Il est recommandé dans SQL Server de s'assurer que toutes les clés étrangères ont au moins un index non clusterisé sur elles.

J'espère que cela éclaircit les choses pour vous, mais n'hésitez pas à demander plus de détails.

13
répondu John Sansom 2017-05-12 18:27:17

Votre meilleur pari de performance est d'utiliser des index sur les champs que vous utilisez fréquemment. Si vous utilisez SQL Server, vous pouvez utiliser profiler pour profiler une base de données spécifique et prendre le fichier qui sort et utiliser l'assistant de réglage pour recevoir des recommandations sur l'emplacement de vos index. J'aime aussi utiliser profiler pour débusquer les procédures stockées de longue durée, j'ai une liste des dix pires délinquants que je publie chaque semaine, garde les gens honnêtes: D.

4
répondu Al Katawazi 2009-02-03 15:02:27

Vous pouvez l'utiliser pour rendre une requête plus efficace. Il vous permet de restructurer les requêtes dans SQL Server pour utiliser une jointure externe au lieu d'une jointure interne qui supprime la nécessité pour les serveurs sql de vérifier s'il y a un null dans la colonne. Vous n'avez pas besoin de mettre ce qualificatif car la relation de clé étrangère l'inforce déjà pour vous.

Donc ceci:

    select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;

Devient ceci:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1;

Cela ne fera pas nécessairement une énorme performance dans les petites requêtes, mais lorsque les tables deviennent grandes, cela peut être plus efficace.

3
répondu kemiller2002 2009-02-03 14:23:51

Je ne sais pas grand - chose sur SQL server, mais dans le cas D'Oracle, avoir une colonne de clé étrangère réduit les performances du chargement des données. C'est parce que la base de données doit vérifier l'intégrité des données pour chaque insertion. Et oui, comme il est déjà mentionné, avoir un index sur la colonne de clé étrangère est une bonne pratique.

1
répondu Shamik 2009-02-03 15:09:52

L'ajout d'une clé étrangère dans la table n'améliorera pas les performances, en disant simplement que si vous insérez un enregistrement dans une base de données de table ProductCategories va essayer de trouver la colonne de clé étrangère a une valeur qui existe dans la valeur de la clé primaire d'une table de produits, cette recherche, l'opération est Ainsi en ajoutant une clé étrangère n'améliorera pas les performances de votre base de données mais elle prendra soin de l'intégrité de votre la base de données. Oui, cela améliorera les performances de votre base de données si vous vérifiez l'intégrité en utilisant une clé étrangère au lieu d'exécuter de nombreuses requêtes pour vérifier que l'enregistrement existe dans la base de données de votre programme.

1
répondu Pankaj Khairnar 2011-08-28 09:43:07

Pour MySQL 5.7, il peut certainement accélérer les requêtes impliquant plusieurs jointures étonnamment bien!

J'ai utilisé 'explain' pour comprendre ma requête et j'ai trouvé que je rejoignais 4-5 tables - où aucune clé n'était utilisée du tout. Je n'ai rien fait d'autre que d'ajouter une clé étrangère à ces tables et le résultat a été une réduction de 90% du temps de chargement. Les requêtes qui ont pris > 5s prennent maintenant 500ms ou moins.

C'est une énorme amélioration!

Et, comme d'autres l'ont mentionné, vous obtenez l'avantage supplémentaire d'assurer intégrité relationnelle.

Au-delà de cela, assurer l'intégrité référentielle a également ses propres avantages de performance. C'est la deuxième commande pour effet d'assurer que les tables qui ont la clé étrangère sont "à jour" avec la table étrangère. Disons que vous avez une table d'utilisateurs et une table de commentaires, et que vous faites des statistiques sur la table de commentaires. Probablement si vous supprimez l'utilisateur, vous ne voulez plus leurs commentaires non plus.

1
répondu Peter Bartlett 2018-06-18 22:03:59

Depuis SQL Server 2008, les clés étrangères peuvent influencer les performances en influençant la façon dont le moteur de base de données choisit d'optimiser la requête. Référez-vous à L'heuristique Star Join dans l'article suivant: https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx

0
répondu LucasF 2017-04-20 01:11:21