Question

J'ai la requête suivante:

SELECT c.*
FROM companies AS c
JOIN users AS u USING(companyid)
JOIN jobs AS j USING(userid)
JOIN useraccounts AS us USING(userid)
WHERE j.jobid = 123;

J'ai les questions suivantes:

  1. La syntaxe USING est-elle synonyme de la syntaxe ON?
  2. Ces jointures sont-elles évaluées de gauche à droite? En d'autres termes, cette requête dit-elle: x = sociétés JOIN utilisateurs; y = x JOIN jobs; z = y JOIN useracounts;
  3. Si la réponse à la question 2 est oui, est-il prudent de supposer que la table companies contient des colonnes companyid, userid et jobid?
  4. Je ne comprends pas comment la clause WHERE peut être utilisée pour sélectionner des lignes dans la table companies quand elle fait référence à l'alias "quot j"
  5. .

Toute aide serait appréciée!

Était-ce utile?

La solution

  1. USING (nom de champ) est un moyen abrégé de dire ON table1.fieldname = table2.fieldname.

  2. SQL ne définit pas "l'ordre" dans lequel JOINS est effectué car ce n'est pas la nature du langage. Évidemment, un ordre doit être spécifié dans l'instruction, mais un INNER JOIN peut être considéré comme commutatif: vous pouvez les lister dans n'importe quel ordre et vous obtiendrez les mêmes résultats.

    Cela dit, lors de la construction de SELECT ... JOIN, en particulier de celui qui inclut LEFT JOIN, il est logique de considérer le troisième JOIN comme reliant la nouvelle table aux résultats du premier JOIN, le quatrième JOIN. en joignant les résultats du second JOIN, et ainsi de suite.

    Plus rarement, l'ordre spécifié peut influer sur le comportement de l'optimiseur de requêtes, en raison de la manière dont il influence les heuristiques.

  3. Non. De la manière dont la requête est assemblée, les entreprises et les utilisateurs ont tous deux un ID société, les travaux ont un ID utilisateur et un ID travail et useraccounts a un ID utilisateur. Cependant, seul l’un des utilisateurs ou de la société a besoin d’un ID utilisateur pour que JOIN puisse fonctionner.

  4. La clause WHERE filtre l'ensemble du résultat - c'est-à-dire toutes les colonnes JOINTES - à l'aide d'une colonne fournie par la table des travaux.

Autres conseils

Je ne peux pas répondre à la question sur la syntaxe USING. C'est bizarre. Je ne l'ai jamais vu auparavant, ayant toujours utilisé une clause ON à la place.

Mais ce que je peux vous dire, c'est que l'ordre des opérations JOIN est déterminé de manière dynamique par l'optimiseur de requêtes lorsqu'il construit son plan de requête, basé sur un système d'heuristiques d'optimisation, parmi lesquelles:

  1. La jointure est-elle effectuée sur un champ de clé primaire? Si tel est le cas, cela devient une priorité élevée dans le plan de requête.

  2. La jointure est-elle exécutée sur un champ de clé étrangère? Cela devient également une priorité élevée.

  3. Existe-t-il un index sur le champ joint? Si tel est le cas, augmentez la priorité.

  4. Une opération JOIN est-elle effectuée sur un champ de la clause WHERE? L'expression de clause WHERE peut-elle être évaluée en examinant l'index (plutôt qu'en effectuant une analyse de table)? Il s’agit d’une opportunité d’optimisation majeure . Elle a donc une priorité majeure.

  5. Quelle est la cardinalité de la colonne jointe? Les colonnes avec une cardinalité élevée donnent à l'optimiseur davantage de possibilités de discriminer les correspondances fausses (celles qui ne satisfont pas la clause WHERE ou la clause ON). Ainsi, les jointures à cardinalité élevée sont généralement traitées avant les jointures à cardinalité faible.

  6. Combien y a-t-il de lignes dans la table jointe? La jonction contre une table avec seulement 100 valeurs créera moins d'explosion de données que la jonction avec une table avec dix millions de lignes.

Quoi qu'il en soit ... le problème est ... il y a BEAUCOUP de variables qui entrent dans le plan d'exécution de la requête. Si vous voulez voir comment MySQL optimise ses requêtes, utilisez la syntaxe EXPLAIN.

Et voici un bon article à lire:

http://www.informit.com/articles/article.aspx? p = 377652

ON EDIT:

Pour répondre à votre quatrième question: vous n’interrogez pas les "entreprises". table. Vous interrogez le produit croisé joint de ALL quatre tables dans vos clauses FROM et USING.

Le " j.jobid " alias est simplement le nom qualifié complet d’une des colonnes de cette collection de tables jointe.

Dans MySQL, il est souvent intéressant de demander à l'optimiseur de requêtes ce qu'il compte faire, avec:

EXPLAIN SELECT [...]

Voir & 7.2.1 Optimisation des requêtes avec EXPLAIN "

VOIR http://dev.mysql.com/doc/ refman / 5.0 / en / join.html

ET commencez à lire ici:

Modifications du traitement des jointures dans MySQL 5.0.12

À partir de MySQL 5.0.12, les jointures naturelles et les jointures avec USING, y compris les variantes de jointure externe, sont traitées conformément à la norme SQL: 2003. L’objectif était d’aligner la syntaxe et la sémantique de MySQL sur NATURAL JOIN et JOIN ... USING selon SQL: 2003. Toutefois, ces modifications dans le traitement des jointures peuvent entraîner des colonnes de sortie différentes pour certaines jointures. De plus, certaines requêtes qui semblaient fonctionner correctement dans les anciennes versions doivent être réécrites pour se conformer à la norme.

Ces changements ont cinq aspects principaux:

  • La façon dont MySQL détermine les colonnes de résultat des opérations de jointure NATURAL ou USING (et donc le résultat de la clause FROM entière).

  • Extension de SELECT * et SELECT nom_de_table. * dans une liste de colonnes sélectionnées.

  • Résolution des noms de colonne dans les jointures NATURAL ou USING.

  • La transformation de jointures NATURAL ou USING dans JOIN ... ON.

  • Résolution des noms de colonne dans l'état ON d'un JOIN ... ON.

Je ne suis pas sûr (e) de la partie ON vs USING (bien que cette le site Web indique que ce sont les mêmes)

En ce qui concerne la question de commande, elle est entièrement spécifique à la mise en œuvre (et probablement à la requête). MYSQL choisit très probablement une commande lors de la compilation de la demande. Si vous souhaitez appliquer un ordre particulier, vous devez "imbriquer" vos requêtes:

SELECT c.*
FROM companies AS c 
    JOIN (SELECT * FROM users AS u 
        JOIN (SELECT * FROM  jobs AS j USING(userid) 
              JOIN useraccounts AS us USING(userid) 
              WHERE j.jobid = 123)
    )

comme pour la partie 4: la clause where limite le nombre de lignes de la table des tâches pouvant être jointes. Donc, s’il existe des lignes qui se joignent en raison des ID utilisateur correspondants mais n’ont pas le bon ID de travail, elles seront alors omises.

1) L’utilisation n’est pas exactement la même chose que sur, mais c’est un raccourci où les deux tables ont une colonne du même nom que vous rejoignez ... voir:

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