Accélérer les jointures internes entre une grande table et une petite table
Cela peut être une question stupide, mais cela peut faire la lumière sur la façon dont les jointures fonctionnent en interne.
Disons que j'ai une grande table L
et une petite table S
(100K lignes vs 100 lignes).
Y aurait-il une différence de vitesse entre les deux options suivantes?:
OPTION 1: OPTION 2:
--------- ---------
SELECT * SELECT *
FROM L INNER JOIN S FROM S INNER JOIN L
ON L.id = S.id; ON L.id = S.id;
Notez que la seule différence est l'ordre dans lequel les tables sont jointes.
Je me rends compte que les performances peuvent varier entre les différentes langues SQL. Si oui, comment MySQL se comparerait-il à Accès?
2 réponses
Non, l'ordre n'a pas d'importance.
Presque tous les SGBDR (tels que MS Access, MySQL, SQL Server, ORACLE, etc.) utilisent un optimiseur basé sur les coûts basé sur les statistiques de colonne. Dans la plupart des situations, l'optimiseur choisira un plan correct. Dans l'exemple que vous avez donné, l'ordre n'a pas d'importance (à condition que les statistiques sont à jour).
Pour décider de la stratégie de requête à utiliser, L'Optimiseur de moteur à réaction utilise statistique. Les facteurs suivants sont certains des facteurs que ces les statistiques sont basées sur:
- , Le nombre d'enregistrements dans une table
- , Le nombre de pages de données dans un tableau
- l'emplacement de La table
- indique si les index sont présents
- comment les index sont uniques
Remarque : vous ne pouvez pas afficher les schémas D'optimisation du moteur de base de données Jet, et vous impossible de spécifier comment optimiser un requête. Toutefois, vous pouvez utiliser le Documenteur de base de données pour déterminer si les index sont présents et unique un index est.
Sur la base de ces statistiques, le Optimizer sélectionne ensuite le meilleur stratégie de requête interne pour traiter avec une requête particulière.
Les statistiques sont mises à jour chaque fois qu'un la requête est compilée. Une requête est marquée pour compiler lorsque vous enregistrez modifications apportées à la requête (ou les tables sous-jacentes) et lors de la la base de données est compactée. Si une requête est signalé pour la compilation, la compilation et la mise à jour des statistiques se produit la prochaine fois que l' exécution d'une requête. La compilation prend généralement d'un deuxième à quatre secondes.
Si vous ajoutez un nombre significatif de les enregistrements de votre base de données, vous devez ouvrez puis enregistrez vos requêtes dans recompilez les requêtes. Par exemple, si vous concevez puis testez une requête en en utilisant un petit ensemble de données d'échantillon, vous doit recompiler la requête après des enregistrements supplémentaires sont ajoutés au la base de données. Lorsque vous faites cela, vous voulez pour vous assurer que la requête optimale la performance est atteinte lorsque votre l'application est en cours d'utilisation.
Réf .
Peut être intéressant: ACC: comment optimiser les requêtes dans Microsoft Access 2.0, Microsoft Access 95 et Microsoft Access 97
La FAQ sur les performances de Microsoft Access de Tony Toews vaut la peine d'être lue.
Je sais Qu'Oracle n'est pas sur votre liste, mais je pense que la plupart des bases de données modernes se comporteront de cette façon.
Vous pouvez voir dans le plan d'exécution suivant, qu'il n'y a pas de différence entre les deux instructions.
C'est un accès complet à chacune des deux tables (pas d'index dans mon cas), et puis un HASH JOIN
. Puisque vous voulez tout des deux tables, les deux tables doivent être lues et jointes, la séquence n'a pas d'impact.
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 100 | 700 | 42 (12)| 00:00:01 |
|* 1 | HASH JOIN | | 100 | 700 | 42 (12)| 00:00:01 |
| 2 | TABLE ACCESS FULL| S | 100 | 300 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| L | 100K| 390K| 38 (8)| 00:00:01 |
---------------------------------------------------------------------------