📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

18行目: 18行目:
*: <code>EXISTS</code>句内のSQL文 (内部クエリ) で値が存在する時、外部クエリが実行される。
*: <code>EXISTS</code>句内のSQL文 (内部クエリ) で値が存在する時、外部クエリが実行される。
*: <code>EXISTS</code>句内のSQL文 (内部クエリ) で値が存在しない時、外部クエリは実行されない。
*: <code>EXISTS</code>句内のSQL文 (内部クエリ) で値が存在しない時、外部クエリは実行されない。
<br><br>
== IN句とEXISTS句の違い ==
パフォーマンスは、データベースエンジンの最適化機能に依存する。<br>
また、インデックスの有無や統計情報によって実行計画が変わる可能性がある。<br>
<br>
また、多くのデータベースエンジンでは、IN句とEXISTS句を内部的に相互に変換することがある。<br>
<br>
==== IN句 ====
サブクエリの結果を全て評価 (全走査) する。<br>
<br>
サブクエリの結果をメモリ上に一時テーブルとして保持する必要がある。<br>
そのため、サブクエリの結果セットが小さい場合に効率的である。<br>
<br>
<syntaxhighlight lang="tsql">
/* IN句の場合 */
SELECT *
FROM orders
WHERE customer_id IN (SELECT id FROM customers WHERE country = 'Korea')
</syntaxhighlight>
<br>
==== EXISTS句 ====
条件に一致するレコードが見つかった時点で評価を終了する。(Semi-join)<br>
<br>
結果セットをメモリに保持する必要がない。<br>
そのため、サブクエリの結果が大きい場合に効率的である。<br>
<br>
<syntaxhighlight lang="tsql">
/* EXISTS句の場合 */
SELECT *
FROM orders o
WHERE EXISTS (SELECT 1 FROM customers c
              WHERE c.id = o.customer_id AND c.country = 'Japan')
</syntaxhighlight>
<br>
==== EXPLAIN PLAN (実行計画) ====
EXPLAIN PLANは、クエリがどのように実行されるかを確認するための機能である。<br>
<br>
EXPLAIN PLANの読み方を以下に示す。<br>
* 実行順序
*: 右から左、上から下に読む。
* 矢印の太さ
*: データ量の大きさを表す。
* コストの%
*: 各操作の相対的なコストを示す。
* 実際の操作
*: Table Scan、Index Seek、Sort等の具体的な処理内容
<br>
EXPLAIN PLANにおいて、以下に示す情報を基に、必要に応じてインデックスの作成やクエリの書き換え等のチューニングを行う。<br>
* テーブルスキャンの発生
* 適切なインデックスの使用
* 予想される行数
* 高コストな操作
<br>
<syntaxhighlight lang="tsql">
/* 一般的な記述 */
SET SHOWPLAN_XML ON;  -- または
SET SHOWPLAN_TEXT ON; -- または
SET STATISTICS PROFILE ON;
SELECT * FROM Users WHERE Age > 20;
SET SHOWPLAN_XML OFF; -- または
SET SHOWPLAN_TEXT OFF; -- または
SET STATISTICS PROFILE OFF;
</syntaxhighlight>
<br>
<syntaxhighlight lang="tsql">
/* より詳細な情報が欲しい場合 */
/* I/O情報も含めた詳細な統計情報 */
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT *
FROM Users
WHERE Age > 20;
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
</syntaxhighlight>
<br>
<syntaxhighlight lang="tsql">
/* クエリを実行せずに実行プランのみ表示する場合 */
/* この場合、Management Studioの実行プランボタン ([Ctrl] + [L]キー) を押下、または */
/* クエリの前にEXPLAINと記述する代わりに実行プランボタンを使用する */
SELECT *
FROM Users
WHERE Age > 20;
GO
</syntaxhighlight>
<br>
-- MySQLの場合
EXPLAIN SELECT * FROM users WHERE age > 20;
<br><br>
<br><br>