digdagからPostgreSQLのクエリを実行するときに、
大量データをtruncate, insertで中間テーブルを作ってから、すぐに次の処理で使いたい場合、統計情報がうまく更新されずにクエリが劣化する場合がある。
対処方法として次の処理を行う前にvacuum analyzeをかけてクエリが重くならないようにする方法があるが、digdagのトランザクション設定をオプションで指定する必要がある。
検証環境
PostgreSQL 13.4
digdag 0.9.41
実行ファイル
pg_query.dig
#PostgreSQLクエリ実行
+pg:
_export:
pg:
host: ${env.postgres_host}
port: ${env.postgres_port}
user: ${env.postgres_user}
password: ${env.postgres_pass}
database: ${env.postgres_database}
# strict_transaction: false
schema: "schema"
+query:
pg>: sql/query.sql
query.sql
/*******************************************************
大量データ処理のため、中間テーブルを作成して、最終テーブルを作成する
*******************************************************/
--中間テーブルのクリア
TRUNCATE
schema.wrk_table
;
--data_tableなので中間テーブルを作成する
INSERT INTO
schema.wrk_table
SELECT
colA
,colB
FROM
schema.data_table
WHERE
colC = 'C'
;
--VACUUM ANALYZE
VACUUM ANALYZE schema.wrk_table;
--最終テーブルを作成
INSERT INTO
schema.final_table
SELECT
t1.colA
,t2.colD
FROM
schema.wrk_table t1
INNER JOIN
schema.name_mst t2
ON t2.colB = t1.colB
;
実行すると以下エラーが発生した
Failed to execute given SQL script [ERROR: VACUUM cannot run inside a transaction block]
VACUUMは同一トランザクション内で使えない。
以下の通り、strict_transactionをflase指定すると問題なく実行できた
クエリが途中で失敗した場合、ロールバックされずに途中まで更新されるので注意すること。
#PostgreSQLクエリ実行
+pg:
_export:
pg:
host: ${env.postgres_host}
port: ${env.postgres_port}
user: ${env.postgres_user}
password: ${env.postgres_pass}
database: ${env.postgres_database}
strict_transaction: false
schema: "schema"
+query:
pg>: sql/query.sql
参考:
公式ページ
Comments
Let's comment your feelings that are more than good