29

次のクエリがあります。

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;

次の質問があります。

  1. USING 構文は ON 構文と同義ですか?
  2. これらの結合は左から右に評価されますか? つまり、このクエリは次のようになりますか? x = company JOIN users; y = x JOIN ジョブ。z = y ユーザーアカウントを結合します。
  3. 質問 2 の答えが「はい」の場合、companys テーブルには companyid、userid、および jobid 列があると想定しても安全ですか?
  4. エイリアス "j" を参照しているときに、WHERE 句を使用して会社テーブルの行を選択する方法がわかりません

どんな助けでも大歓迎です!

4

7 に答える 7

29
  1. USING (fieldname) は、ON table1.fieldname = table2.fieldname の省略形です。

  2. SQL は、言語の性質ではないため、JOINS が実行される「順序」を定義しません。明らかに、ステートメントで順序を指定する必要がありますが、INNER JOIN は交換可能と見なすことができます。それらを任意の順序でリストしても、同じ結果が得られます。

    そうは言っても、SELECT ... JOIN、特に LEFT JOIN を含むものを構築する場合、3 番目の JOIN を最初の JOIN の結果に新しいテーブルを結合するものと見なし、4 番目の JOIN を2 番目の JOIN の結果など。

    ごくまれに、指定された順序がヒューリスティックに影響を与えるため、クエリ オプティマイザーの動作に影響を与えることがあります。

  3. いいえ。クエリを組み立てる方法では、company と users の両方に companyid があり、jobs に userid と jobid があり、useraccounts に userid がある必要があります。ただし、JOIN が機能するためにユーザー ID が必要なのは、企業またはユーザーの 1 つだけです。

  4. WHERE 句は、ジョブ テーブルによって提供される列を使用して、結果全体 (つまり、結合されたすべての列) をフィルター処理します。

于 2008-10-23T04:38:11.113 に答える
11

USING構文については少し答えられません。それは変だ。代わりに常に ON 句を使用していたため、これまで見たことがありません。

しかし、私言えることは、JOIN 操作の順序は、最適化ヒューリスティックのシステムに基づいてクエリ プランを構築するときに、クエリ オプティマイザーによって動的に決定されるということです。

  1. JOIN は主キー フィールドで実行されますか? その場合、これはクエリ プランで高い優先度を取得します。

  2. JOIN は外部キー フィールドで実行されますか? これも優先度が高くなります。

  3. 結合されたフィールドにインデックスは存在しますか? その場合は、優先順位を上げてください。

  4. WHERE 句のフィールドに対して JOIN 操作が実行されていますか? (テーブル スキャンを実行するのではなく) インデックスを調べることによって WHERE 句の式を評価できますか? これは主要な最適化の機会であるため、主要な優先度が上がります。

  5. 結合された列のカーディナリティは? カーディナリティの高い列は、オプティマイザーが誤った一致 (WHERE 句または ON 句を満たさないもの) を識別する機会を増やすため、通常、カーディナリティの高い結合はカーディナリティの低い結合よりも前に処理されます。

  6. 結合されたテーブルには実際に何行ありますか? 値が 100 個しかないテーブルに対する結合は、1,000 万行のテーブルに対する結合よりも、データ爆発が少なくなります。

とにかく...要点は...クエリ実行計画に入る変数がたくさんあるということです。MySQL がクエリを最適化する方法を確認したい場合は、EXPLAIN 構文を使用してください。

そして、ここに読むべき良い記事があります:

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


編集時:

4 番目の質問に答えるには、「会社」テーブルに対してクエリを実行していません。FROM 句と USING 句で、4 つのテーブルすべての結合クロス積をクエリしています。

「j.jobid」エイリアスは、結合されたテーブルのコレクション内の列の 1 つの完全修飾名です。

于 2008-10-23T03:43:45.357 に答える
4

MySQL では、クエリ オプティマイザに何をする予定かを尋ねると、興味深いことがよくあります。

EXPLAIN SELECT [...]

「7.2.1 EXPLAINによるクエリの最適化」参照

于 2009-04-15T05:29:00.143 に答える
0

ON と USING の部分についてはわかりません (ただし、このWeb サイトでは同じであると述べています)。

順序付けの質問に関しては、その完全な実装 (およびおそらくクエリ) 固有です。MYSQL は、リクエストをコンパイルするときに注文を選択する可能性が最も高いです。特定の順序を強制したい場合は、クエリを「ネスト」する必要があります。

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)
    )

パート 4 について: where 句は、jobs テーブルのどの行が JOIN される資格があるかを制限します。そのため、ユーザー ID が一致するために結合される行があるが、正しいジョブ ID がない場合、それらは省略されます。

于 2008-10-23T03:45:14.357 に答える
0

1)使用はonとまったく同じではありませんが、両方のテーブルに結合している同じ名前の列がある場合の省略形です...参照:http://www.java2s.com/Tutorial/MySQL/0100__Table -Join/The キーワード USING は、tableJoins.htm 中の ON キーワードの代わりに使用できます。

私の意見では読みにくいので、結合を綴ります。

3) このクエリからは明確ではありませんが、そうではないと思います。

2)他のテーブルを介して参加していると仮定すると(すべてが会社に直接参加しているわけではありません)、このクエリの順序は重要です...以下の比較を参照してください:

オリジナル:

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

私が示唆していると思われること:

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

ここで、ジョブとユーザーアカウントに参加する回線を切り替えることができます。

すべてが会社に参加した場合、次のようになります。

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

これは論理的に意味がありません...各ユーザーが独自の会社を持っている場合を除きます。

4.) SQL の魔法は、特定の列のみを表示できることですが、それらはすべて並べ替えとフィルタリング用です...

戻ってきたら

SELECT c.*, j.jobid....  

何をフィルタリングしているのかははっきりとわかりますが、データベースサーバーは、行を出力するかどうかを気にしません。

于 2008-10-23T04:17:23.340 に答える
0

http://dev.mysql.com/doc/refman/5.0/en/join.htmlを参照してください。

そして、ここから読み始めてください:


MySQL 5.0.12 での結合処理の変更

MySQL 5.0.12 から、自然結合および USING を使用した結合 (外部結合バリアントを含む) は、SQL:2003 標準に従って処理されます。目標は、SQL:2003 に従って NATURAL JOIN および JOIN ... USING に関して MySQL の構文とセマンティクスを調整することでした。ただし、結合処理におけるこれらの変更により、一部の結合で異なる出力列が生じる可能性があります。また、古いバージョンでは正しく動作するように見えた一部のクエリは、標準に準拠するように書き直す必要があります。

これらの変更には、次の 5 つの主な側面があります。

  • MySQL が NATURAL または USING 結合操作の結果列 (したがって FROM 句全体の結果) を決定する方法。

  • SELECT * および SELECT tbl_name.* を選択した列のリストに展開します。

  • NATURAL または USING 結合での列名の解決。

  • NATURAL または USING 結合の JOIN ... ON への変換。

  • JOIN ... ON の ON 条件での列名の解決。

于 2008-10-23T03:42:09.823 に答える