postgresqlデータベース更新の更新が遅い理由(解決済み)

postgresqlデータベース更新の更新が遅い理由(解決済み)

過去数日間で、更新ステートメント(約140,000個のデータ)が見つかりました。1時間実行されていて、完了していません。
いくつかの解決策があります。
更新ステートメントは、一時テーブルから値を更新します
特定のデータがあるため、別の公式テーブルに移動します。秘密にしておく必要があります。スクリーンショットは撮りません。一般的なアイデアと方法について話します。

1.ステートメントに問題があるかどうかを確認します

2つの同一のテーブルとデータをコピーします。ステートメントを手動で実行し、1分以内に正常に実行されることを確認して、ステートメントが正しいことを確認できるようにします。

2.アップデータに影響を与える要因を見つけます

私の最初の反応は、待機またはデッドロックを引き起こすロックとロックがあるかどうかです

クエリロック

select w1.pid as 等待进程,
w1.mode as 等待锁模式,
w2.usename as 等待用户,
w2.query as 等待会话,
b1.pid as 锁的进程,
b1.mode 锁的锁模式,
b2.usename as 锁的用户,
b2.query as 锁的会话,
b2.application_name 锁的应用,
b2.client_addr 锁的IP地址,
b2.query_start 锁的语句执行时间
from pg_locks w1
join pg_stat_activity w2 on w1.pid=w2.pid
join pg_locks b1 on w1.transactionid=b1.transactionid and w1.pid!=b1.pid
join pg_stat_activity b2 on b1.pid=b2.pid
where not w1.granted;
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid='62560'

ロックがあることを確認し、ロックプロセスを強制終了して、サービスを再起動します。追跡を続けて、5分後にロックが再び表示されることを確認します。何度か試しましたが、ロックとは関係がないことがわかりました。

3.クエリパラメータ

私が最初に見たのはshared_buffersパラメーターでしたが、問題はありませんでした。
ここに画像の説明を挿入

4.シュリンクテーブルVACUUM

データプロセスをクエリすると、クエリテーブルが縮小される前に自動縮小も10分間実行されたことがわかりました。

サーバーの監視に使用され、プロセスを照会でき、時間の消費はロックに関連しています

SELECT 

C.relname 对象名称,
l.locktype 可锁对象的类型,
l.pid 进程id,
l.MODE 持有的锁模式,
l.GRANTED 是否已经对锁进行授权,
l.fastpath,
psa.datname 数据库名称,
psa.usesysid 用户id,
psa.usename 用户名称,
psa.application_name 应用程序名称,
psa.client_addr 连接的IP地址,
psa.client_port 连接使用的TCP端口号,
psa.backend_start 进程开始时间,
psa.xact_start 事务开始时间,
psa.query_start 事务执行此语句时间,
psa.state_change 事务状态改变时间,
psa.wait_event_type 等待事件类型,
psa.wait_event 等待事件,
psa.STATE 查询状态,

backend_xid 事务是否有写入操作,
backend_xmin 是否执事务快照,

psa.query 执行语句,
now( ) - query_start 持续时间

FROM

pg_locks l
INNER JOIN pg_stat_activity psa ON ( psa.pid = l.pid )
LEFT OUTER JOIN pg_class C ON ( l.relation = C.oid )
-- where l.relation = 'tb_base_apparatus'::regclass

where relkind ='r'
ORDER BY query_start asc

クエリが自動的にクリーンアップされたテーブルに到達するかどうか

SELECT
    c.relname 表名,
    (current_setting('autovacuum_analyze_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_analyze_scale_factor')::NUMERIC(12,4))*reltuples AS 自动分析阈值,
    (current_setting('autovacuum_vacuum_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_vacuum_scale_factor')::NUMERIC(12,4))*reltuples AS 自动清理阈值,
    reltuples::DECIMAL(19,0) 活元组数,
    n_dead_tup::DECIMAL(19,0) 死元组数
FROM
    pg_class c 

LEFT JOIN pg_stat_all_tables d

    ON C.relname = d.relname
WHERE
    c.relname LIKE'tb%'  AND reltuples > 0
    AND n_dead_tup > (current_setting('autovacuum_analyze_threshold')::NUMERIC(12,4))+(current_setting('autovacuum_analyze_scale_factor')::NUMERIC(12,4))*reltuples;

すると、死んだ祖先が多すぎることに
気づき、手動でテーブルを縮小してすぐに更新しました。

VACUUM FULL VERBOSE 表名;
VACUUM FULL VERBOSE ANALYZE 表名;

5.まとめ

この場合、SQLステートメントに問題がないことを確認してから、EXPLAINにロックがあるかどうかを確認し、データベースパラメータ、データベースのパフォーマンス上の理由かどうかを確認して、最後に必要かどうかを確認する必要があります。テーブルを縮小するには

おすすめ

転載: blog.csdn.net/yang_z_1/article/details/113237696