
リクエストにそれほど時間がかかったのはなぜですか? インデックスが使用されないのはなぜですか?
おそらく誰もがPostgreSQLでEXPLAINを聞いたことがあるでしょう。 しかし、その使い方を理解している人は多くありません。 彼自身は長い間、理解しやすい教科書を見つけることができませんでした(検索が不十分ですか?)。
この素晴らしいツールに対処したい人にこの記事が役立つことを願っています。
これは翻訳ではなく、著者による資料の処理です。ギヨーム・レラージの
EXPLAINを
理解しています。 情報の一部が省略されているため、オリジナルを読むことを強くお勧めします。
そんなに怖くない
クエリを最適化するには、PostgreSQLカーネルの背後にあるロジックを理解することが非常に重要です。
説明しようとします。 実際、すべてがそれほど複雑ではありません。 EXPLAINは、カーネルが各特定のリクエストで何をするかを理解するために必要な情報を表示します。 EXPLAINコマンドの出力を並行して検討し、PostgreSQLの内部で何が起こっているのかを理解します。 これは、PostgreSQL 9.2以降に適用されます。
私たちのタスク:
- EXPLAINコマンドの出力を読んで理解することを学ぶ
- クエリ実行時にPostgreSQLで何が起こるかを理解する
最初のステップ
100万行のテストパターンで
猫を訓練します
CREATE TABLE foo (c1 integer, c2 text); INSERT INTO foo SELECT i, md5(random()::text) FROM generate_series(1, 1000000) AS i;
データを読み取ってみましょう
EXPLAIN SELECT * FROM foo;
クエリプラン
-fooのSeqスキャン(コスト= 0.00..18334.00行= 1,000,000幅= 37)
(1行)
テーブルからデータを読み取るには、いくつかの方法があります。 この場合、EXPLAINは、
Seq Scan
が使用されていることを報告します-順次、ブロック
foo
、
foo
テーブルからのデータの読み取り
cost
とは? これは時間ではありませんが、操作のコストを評価するために設計された、ある種の真空コンセプトの球状です。 最初の値
0.00
は、最初の行を取得するコストです。 2番目
18334.00
すべての行を取得するコスト。
rows
は、
Seq Scan
操作の実行時に返されるおよその行数です。 この値は、スケジューラーによって返されます。 私の場合、テーブルの実際の行数と一致します。
width
-1行の平均サイズ(バイト単位)。
10行追加してみましょう。
INSERT INTO foo SELECT i, md5(random()::text) FROM generate_series(1, 10) AS i; EXPLAIN SELECT * FROM foo;
クエリプラン
-fooのSeqスキャン(コスト= 0.00..18334.00行= 1,000,000幅= 37)
(1行)
rows
の値は変更され
rows
いません。 テーブルの統計は古いです。 統計を更新するには、
ANALYZE
コマンドを呼び出します。
ANALYZE foo; EXPLAIN SELECT * FROM foo;
クエリプラン
-fooのSeqスキャン(コスト= 0.00..18334.10行= 1000010幅= 37)
(1行)
rows
に正しい行数が表示されるようになりました。
ANALYZEを実行するとどうなりますか?
- 特定の数のテーブル行がランダムに選択されます。
- 表の各列の統計が収集されます。
ANALYZEが読み込む行数は、
default_statistics_target
パラメーターによって異なります。
実データ
EXPLAINコマンドの出力で上で見たのは、スケジューラの期待だけです。 それらを実際のデータの結果と比較してみましょう。
EXPLAIN (ANALYZE)
を使用します。
EXPLAIN (ANALYZE) SELECT * FROM foo;
クエリプラン
-fooのSeqスキャン(コスト= 0.00..18334.10行= 1000010幅= 37)(実際の時間= 0.012..61.524行= 1000010ループ= 1)
合計ランタイム:90.944ミリ秒
(2行)
そのような要求は現実的に実行されます。 したがって、INSERT、DELETE、またはUPDATEについてEXPLAIN(ANALYZE)を実行すると、データが変更されます。 注意してください! そのような場合は、ROLLBACKコマンドを使用してください。
コマンド情報の出力が追加されました。
actual time
-最初の行とすべての行をそれぞれ取得するために費やされたリアルタイム(ミリ秒単位)。
rows
-
Seq Scan
受信した実際の行数。
loops
-操作
Seq Scan
を実行しなければならなかった回数。
Total runtime
-リクエストの合計ランタイム。
もっと...
最初の部分については、おそらく十分でしょう。
パート2パート3