14. 実行計画
• 実行計画の確認方法
• コマンドで実行する場合は、DBMSによって異なります。
• このテキストではPostgreSQLの環境で検証していきます。
14
DBMS コマンド
Oracle SET AUTOTRACE TRACEONLY
SQL Server SET SHOWPLAN_TEXT ON
DB2 EXPLAIN ALL WITH SNAPSHOT FOR SQL文
PostgreSQL EXPLAIN [ANALYZE] SQL文
MySQL EXPLAIN EXTENDED SQL文
15. 実行計画
• 実行計画で使用するテーブル定義
• 今回の検証で使用するのは以下の3つのテーブルです。
• tableAとtableBはそれぞれ10万件ずつのレコードが存在します。
15
tableA インデックス
物理名 型 primary key 1 a_id
a_id integer 〇
name varchar(50)
value real
tableB インデックス
物理名 型 primary key 1 b_id
b_id integer 〇 2 a_id
a_id integer
value real
40. Nested Loops
• まずは以下のSQL文の実行計画を確認します。
• 実行結果は2レコードになるSQL文になっています。
40
axizdb_explain=> EXPLAIN SELECT * FROM tableA a
INNER JOIN tableB b
ON a.a_id = b.a_id
WHERE b.value = 1
AND b.a_id BETWEEN 10 AND 200;
47. Sort Merge
• 次はWHERE句を無くしてみます。
• 100000レコード出力されるSQLになります。
47
axizdb_explain=> EXPLAIN SELECT * FROM tableA a
INNER JOIN tableB b
ON a.a_id = b.a_id
order by b.a_id;
61. 演習問題
• 演習問題
• 以下のSQL文の実行計画を確認してみましょう。
61
-- ORDER BY ①
SELECT * FROM tableB
WHERE a_id BETWEEN 1 AND 100
ORDER BY b_id;
-- ORDER BY ②
SELECT * FROM tableB
WHERE a_id BETWEEN 1 AND 100
ORDER BY a_id;
-- ORDER BY ③
SELECT * FROM tableB
WHERE a_id BETWEEN 1 AND 100
ORDER BY a_id DESC;
62. 演習問題
• 演習問題
62
-- LIMIT
SELECT * FROM tableB
WHERE a_id BETWEEN 1 AND 100
LIMIT 50;
-- ORDER BY & LIMIT
SELECT * FROM tableB
WHERE a_id BETWEEN 1 AND 100
ORDER BY b_id
LIMIT 50;
63. 演習問題
• 演習問題
63
-- GROUP BY
SELECT value, count(*)
FROM tableB
GROUP BY value;
-- GROUP BY & HAVING
SELECT value, count(*)
FROM tableB
GROUP BY value
HAVING count(*) > 100;
-- COUNT
SELECT count(*)
FROM tableB;
64. 演習問題
• 演習問題
64
-- GROUP BY & ORDER BY
SELECT value FROM tableB
GROUP BY value
ORDER BY value;
-- WHERE & GROUP BY
SELECT value, count(*)
FROM tableB
WHERE b_id < 1000
GROUP BY value;
65. 演習問題
• 演習問題
65
-- UNION ALL
SELECT a_id FROM tableA
UNION ALL
SELECT a_id FROM tableB;
-- UNION
SELECT a_id FROM tableA
UNION
SELECT a_id FROM tableB;
-- EXCEPT
SELECT a_id FROM tableA
EXCEPT
SELECT a_id FROM tableB;
66. 演習問題
• 演習問題
66
-- EXISTS ①
SELECT * FROM tableA a
WHERE EXISTS (SELECT * FROM tableB
WHERE a_id = a.a_id AND value = 1
AND a_id BETWEEN 1 AND 200);
-- EXISTS ②
SELECT * FROM tableB b
WHERE a_id BETWEEN 1 AND 200
AND value = 1
AND EXISTS (SELECT * FROM tableA
WHERE a_id = b.a_id);
67. 演習問題
• 演習問題
67
-- EXISTS ③
SELECT * FROM tableA a
WHERE EXISTS (SELECT * FROM tableB
WHERE a_id = a.a_id
AND value = 1);
-- EXISTS ④
SELECT * FROM tableB b
WHERE value = 1
AND EXISTS (SELECT * FROM tableA
WHERE a_id = b.a_id);
68. 演習問題
• 演習問題
68
-- INを使ったサブクエリ ①
SELECT * FROM tableA
WHERE a_id in (SELECT a_id FROM tableB
WHERE value = 1
AND a_id BETWEEN 1 AND 200);
-- INを使ったサブクエリ ②
SELECT * FROM tableB b
WHERE a_id BETWEEN 1 AND 200
AND value = 1
AND a_id IN (SELECT a_id FROM tableA);