PostgreSQLクエリの実行時間取得
質問内容
DECLARE @StartTime datetime,@EndTime datetime
SELECT @StartTime=GETDATE()
select distinct born_on.name
from born_on,died_on
where (FLOOR(('2012-01-30'-born_on.DOB)/365.25) <= (
select max(FLOOR((died_on.DOD - born_on.DOB)/365.25))
from died_on, born_on
where (died_on.name=born_on.name))
)
and (born_on.name <> All(select name from died_on))
SELECT @EndTime=GETDATE()
SELECT DATEDIFF(ms,@StartTime,@EndTime) AS [Duration in millisecs]
クエリタイムを取得することができません。代わりに以下のエラーが表示されます。
sql:/home/an/Desktop/dbms/query.sql:9: ERROR: syntax error at or near "@"
LINE 1: DECLARE @StartTime datetime,@EndTime datetime
どのように解決するのですか?
実行時間を測定する方法はさまざまで、それぞれに長所と短所があります。しかし、何をするにしても、ある程度は オブザーバ効果 が適用されます。つまり、測定そのものが結果を歪めてしまう可能性があるのです。
1.
EXPLAIN ANALYZE
を前置することができます。
EXPLAIN ANALYZE
これは、推定コストと実際に計測された時間を含むクエリプラン全体を報告します。クエリは
実際に実行される
(副作用があればそれも含めて!) です。動作は
SELECT
,
INSERT
,
UPDATE
,
DELETE
.
私が適合させたバージョンのクエリが、実際に速くなったかどうかを確認します。
EXPLAIN ANALYZE
SELECT DISTINCT born_on.name
FROM born_on b
WHERE date '2012-01-30' - b.dob <= (
SELECT max(d1.dod - b1.dob)
FROM born_on b1
JOIN died_on d1 USING (name) -- name must be unique!
)
AND NOT EXISTS (
SELECT FROM died_on d2
WHERE d2.name = b.name
);
ウォームキャッシュでより比較可能な時間を得るために、2回ほど実行します。 いくつかのオプション があり、詳細度を調整することができます。
主に興味があるのは 総実行時間 であれば、作ってください。
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF)
大抵の場合
TIMING
が重要です -。
マニュアルを
TIMING
実際の起動時間や各ノードでの滞在時間を出力に含めます。
システムクロックを繰り返し読み取るオーバーヘッドは、システムによってはクエリの速度を著しく低下させます。
クエリの速度を著しく低下させる可能性があるため、このパラメータを
パラメータを
FALSE
に設定すると便利です。
に設定すると便利です。ステートメント全体の実行時間は、このオプションでノードレベルのタイミングをオフにした場合でも、常に測定されます。
このオプションでノードレベルのタイミングをオフにした場合でも、ステートメント全体の実行時間は常に測定されます。[...]
EXPLAIN ANALYZE
対策
サーバ上で
で、サーバOSのサーバ時刻を使用します。
ネットワーク遅延を除く
. しかし
EXPLAIN
はクエリプランを出力するために若干のオーバーヘッドを追加します。
2. psql で
\timing
または
\timing
を psql で使用することもできます。
ピーターが実演しているように
\timing [ on | off ]
パラメータを指定すると、各SQL文の所要時間の表示を の表示をオンまたはオフにします。パラメータを指定しない場合は、表示のオン・オフを切り替えます。 とOFFを切り替えます。表示はミリ秒単位で、1秒以上の場合は分:秒の形式で表示されます。 秒以上の場合は、分:秒の形式で表示されます。 フィールドが追加されます。
重要な違いです。 psqlのメジャー クライアント上で はローカル OS からのローカルタイムを使用しているので、時間 はネットワーク遅延を含む . これは無視できるほどの差であったり 巨大な になる可能性があります。
3. 有効化
log_duration
これは、おそらく測定あたりのオーバーヘッドが最も少なく、最も歪んだタイミングを生成します。しかし、スーパーユーザーでなければならず、サーバーの設定を調整しなければならず、単一のクエリの実行だけを対象とすることはできず、サーバーログを読まなければならないので、少し強引です (ただし、リダイレクトして
stdout
).
log_duration
(
boolean
)
完了したステートメントの期間をログに記録するようにします。デフォルトは
デフォルトは
off
. スーパーユーザのみがこの設定を変更することができます。
拡張クエリプロトコルを使用するクライアントでは、Parse、Bind、およびExecuteの各ステップの継続時間は独立して記録されます。 バインド、および実行の各ステップは独立してログに記録されます。
のような関連する設定があります。
log_min_duration_statement
.
4. による精密な手動測定
clock_timestamp()
<ブロッククオート
clock_timestamp()
は実際の現在時刻を返すので、その値は1つのSQLコマンド内でも変化します。
filiprem提供
は、アドホッククエリの実行時間を可能な限り正確に取得するための素晴らしい方法です。最新のハードウェアでは、タイミングのオーバーヘッド
は
は重要ではありませんが、ホスト OS によっては大きく変化することがあります。サーバー アプリケーションで確認する
pg_test_timing
.
その他は、ほとんどこのようにオーバーヘッドをフィルタリングすることができます。
DO
$do$
DECLARE
_timing1 timestamptz;
_start_ts timestamptz;
_end_ts timestamptz;
_overhead numeric; -- in ms
_timing numeric; -- in ms
BEGIN
_timing1 := clock_timestamp();
_start_ts := clock_timestamp();
_end_ts := clock_timestamp();
-- take minimum duration as conservative estimate
_overhead := 1000 * extract(epoch FROM LEAST(_start_ts - _timing1
, _end_ts - _start_ts));
_start_ts := clock_timestamp();
PERFORM 1; -- your query here, replacing the outer SELECT with PERFORM
_end_ts := clock_timestamp();
-- RAISE NOTICE 'Timing overhead in ms = %', _overhead;
RAISE NOTICE 'Execution time in ms = %' , 1000 * (extract(epoch FROM _end_ts - _start_ts)) - _overhead;
END
$do$;
繰り返し時間をとり(ここでは3つのタイムスタンプで最低限)、最小間隔を選んでタイミングオーバーヘッドの保守的な見積もりとします。また、関数を実行することで
clock_timestamp()
を数回実行することで、ウォームアップすることができます(お使いのOSにとって重要な場合)。
ペイロードクエリの実行時間を測定した後、実際の時間に近づけるために推定オーバーヘッドを差し引きます。
もちろん、安いクエリでは100000回ループしたり、できることなら100000行のテーブルで実行したほうが、気が散るノイズを取る意味があるのですが。
関連
-
[解決済み] PostgreSQLの場合。PostgreSQLのテーブルを表示する
-
[解決済み] PostgreSQLの "DESCRIBE TABLE"
-
[解決済み] PostgreSQL コマンドラインユーティリティ: psql を終了する方法
-
[解決済み] MongoDBに "like "を使ってクエリを実行する方法
-
[解決済み] PostgreSQLのユーザーパスワードを変更する方法を教えてください。
-
[解決済み] ATTACHで開いたSQLiteデータベースファイルのテーブルを一覧表示するにはどうすればよいですか?
-
[解決済み] どのバージョンのPostgreSQLを使用していますか?
-
[解決済み] PostgreSQLからのPL/pgSQL出力をCSVファイルに保存する
-
[解決済み] Javaでメソッドの実行時間を計るにはどうしたらいいですか?
-
[解決済み] VARCHARとCHARの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[エラー処理] [MySQL] [Err] 1241 - オペランドは 1 つのカラムを含む必要があります。
-
windows mysql prompt access denied for user ''@'localhost' to database.
-
[解決済み] SQLのカラム名があいまいな場合のクエリエラー
-
[解決済み] 指定されたスキーマにテーブルが存在するかどうかを確認する方法
-
[解決済み] SQL Server で複数行のテキストを 1 つのテキスト文字列に連結する方法
-
[解決済み] 各グループの上位1行を取得
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み] "ON UPDATE CASCADE "を使用する場合について
-
[解決済み] Selectステートメントで特定のフィールドの重複を検索する
-
[解決済み] Postgres でサブクエリを使用してテーブルの行を更新する