質問

明示的内部結合と暗黙的内部結合では効率に違いはありますか?例えば:

SELECT * FROM
table a INNER JOIN table b
ON a.id = b.id;

SELECT a.*, b.*
FROM table a, table b
WHERE a.id = b.id;
役に立ちましたか?

解決

パフォーマンスの点では、これらはまったく同じです (少なくとも SQL Server では)。

追伸:注意してください。 IMPLICIT OUTER JOIN この構文は SQL Server 2005 以降非推奨になりました。( IMPLICIT INNER JOIN 質問で使用されている構文は引き続きサポートされます)

「古いスタイル」の JOIN 構文の非推奨:部分的なものにすぎない

他のヒント

個人的には、テーブルが結合されることとその結合方法が明確になるため、結合構文の方が好きです。8 つの異なるテーブルから選択し、where で多くのフィルタリングを行っている大規模な SQL クエリを比較してみてください。結合構文を使用すると、テーブルが結合されている部分と行をフィルター処理している部分を分離できます。

MySQL 5.1.51 では、両方のクエリに同一の実行プランがあります。

mysql> explain select * from table1 a inner join table2 b on a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.02 sec)

mysql> explain select * from table1 a, table2 b where a.pid = b.pid;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
|  1 | SIMPLE      | b     | ALL  | PRIMARY       | NULL | NULL    | NULL         |  986 |       |
|  1 | SIMPLE      | a     | ref  | pid           | pid  | 4       | schema.b.pid |   70 |       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------+
2 rows in set (0.00 sec)

table1 166208 行あります。 table2 約1000行あります。

これは非常に単純なケースです。より複雑な場合にクエリ オプティマイザーが混乱して別のプランを生成しないということは決して証明できません。

2 番目の構文には、望ましくない相互結合の可能性があります。対応する WHERE 句がなくても、FROM 部分にテーブルを追加できます。これは有害であると考えられています。

あなたが与えた最初の答えは、ANSI結合構文として知られているものを使用しており、もう1つは有効で、任意のリレーショナルデータベースで機能します。

ANSI 結合構文を使用する必要があるという grom の意見に同意します。彼らが言ったように、主な理由は明確にするためです。テーブルを結合する述語や、ANSI 結合構文で返される行を制限する述語を含む多くの述語を含む where 句を使用するのではなく、どの条件がテーブルの結合に使用され、どの条件がテーブルの結合を制限するために使用されているかを盲目的に明確にします。結果。

@lomaxx:明確にしておきますが、上記の構文は両方とも SQL Serv 2005 でサポートされていると確信しています。ただし、以下の構文はサポートされていません

select a.*, b.*  
from table a, table b  
where a.id *= b.id;

具体的には、外部結合 (*=) はサポートされていません。

パフォーマンスの点では、これらは (少なくとも SQL Server では) まったく同じですが、この結合構文は非推奨であり、SQL Server2005 ではそのままではサポートされていないことに注意してください。

あなたは、非推奨の *= および =* 演算子と「外部結合」。

指定された 2 つの形式をテストしたところ、SQL Server 2008 データベースで適切に動作しました。私の場合、同じ実行計画が得られましたが、これが常に正しいとは自信を持って言えませんでした。

一部のデータベース (特に Oracle) では、結合の順序によってクエリのパフォーマンスに大きな違いが生じる可能性があります (テーブルが 3 つ以上ある場合)。あるアプリケーションでは、文字通り 2 桁の差があった場合もありました。正しいヒント構文を使用している場合、内部結合構文を使用すると、これを制御できます。

使用しているデータベースは指定されていませんが、SQL Server または MySQL の可能性が高く、実質的な違いはありません。

Leigh Caldwell 氏が述べているように、クエリ オプティマイザーは、機能的には同じ SQL ステートメントに見えるものに基づいて、異なるクエリ プランを生成できます。これについてさらに詳しく知りたい場合は、次の 2 つのブログ投稿をご覧ください。

Oracle Optimizer チームからの 1 件の投稿

「構造化データ」ブログからの別の投稿

面白いと思っていただければ幸いです。

パフォーマンスに関しては、違いはありません。明示的な結合構文は、from 句でテーブル間の関係を明確に定義し、where 句を乱雑にしないため、私にとってはすっきりしているように思えます。

私の経験では、where-clause を使用したクロス結合構文を使用すると、特に Microsoft SQL 製品を使用している場合に、脳を損傷した実行プランが生成されることがよくあります。たとえば、SQL Server がテーブルの行数を推定しようとする方法は、非常にひどいものです。内部結合構文を使用すると、クエリの実行方法をある程度制御できます。したがって、実際的な観点から見ると、現在のデータベース テクノロジの隔世的な性質を考慮すると、内部結合を使用する必要があります。

基本的に、この 2 つの違いは、一方が古い方法で書かれ、もう一方が現代的な方法で書かれていることです。個人的には、内側、左、外側、右の定義を使用する最新のスクリプトの方が説明がわかりやすく、コードが読みやすくなるため好みです。

内部結合を扱う場合、可読性には実際の違いはありませんが、左結合と右結合を扱う場合は、古い方法では次のような結果が得られるため、複雑になる可能性があります。

SELECT * 
FROM table a, table b
WHERE a.id = b.id (+);

上記は、以下とは対照的に、左結合を記述する古い方法です。

SELECT * 
FROM table a 
LEFT JOIN table b ON a.id = b.id;

視覚的にわかるように、スクリプトの記述方法が最新のものになっているため、クエリがより読みやすくなっています。(ちなみに、右結合の場合も同様で、外部結合の場合は少し複雑になります)。

定型文に戻ると、SQL コンパイラーはクエリを同じ方法で処理するため、クエリの記述方法に違いはありません。私は、高齢者と若い人を含む多くの人々が Oracle データベースにその両方を混在させて書き込んでいるのを見てきました。繰り返しになりますが、結局はスクリプトがどれだけ読みやすいか、そして一緒に開発しているチームによって決まります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top