我正在嘗試從另一個表更新表,請求最終成功,但沒有更新任何行。每個表包含約 32M 行。我在 PostgreSQL 11.12 上運行。
這是 2 個表(我已洗掉請求中未使用的列):
CREATE TABLE IF NOT EXISTS public.sirene_geo
(
siret character varying(50) NOT NULL,
x numeric,
y numeric,
CONSTRAINT sirene_geo_etablissement_pkey PRIMARY KEY (siret)
)
CREATE TABLE IF NOT EXISTS public.sirene_eta
(
siret character varying(50) NOT NULL,
latitude numeric,
longitude numeric,
CONSTRAINT sirene_stock_etablissement_pk PRIMARY KEY (siret)
)
更新請求:
UPDATE sirene_eta eta
SET longitude = x,
latitude = y
FROM sirene_geo geo
WHERE eta.siret = geo.siret
在 pgAdmin (v5.4) 上,“受影響的行”欄位顯示為 -1。
Postgres 正在使用散列連接策略來完成更新。此外,sirene_geo 中的行數少于 sirene_eta,但 Postgres 仍在 sirene_geo 上構建哈希表(因此導致某些行不匹配)。
當我嘗試在子查詢表中使用限制進行更新時,它可以作業,但它使用的是嵌套回圈策略,這絕對不適合更新整個表。
更新:
沒有并發寫入活動。我檢查了日志,確實有一個錯誤:
ERROR: could not write to file "base/pgsql_tmp/pgsql_tmp9264.8256": No space left on device
uj5u.com熱心網友回復:
您的存盤設備空間不足。在啟動大的UPDATE. 洗掉可有可無的檔案(與資料庫無關)。或者以某種方式縮小你的資料庫。
平原VACUUM 可能會完成這項作業。或者VACUUM FULL(阻止并發訪問)以大幅縮減物理存盤。如果您負擔不起阻止,請考慮使用非阻止社區工具之一。看:
- 優化 Postgres 對時間戳范圍的查詢
VACUUM FULL最好不要在sirene_eta(目標表)上,無論如何都會重用死元組UPDATE(在 plain 之后VACUUM)。并確保VACUUM不會被長時間運行的事務阻塞。看:
- 不結束資料庫事務的后果是什么?
- 為什么這個 PostgreSQL 事務給出“警告:沒有正在進行的事務”
無論您做什么,如果您不希望所有目標行都實際更改,請添加一個WHERE條件來過濾空更新(全額費用!)
UPDATE sirene_eta eta
SET longitude = geo.x
, latitude = geo.y
FROM sirene_geo geo
WHERE eta.siret = geo.siret
AND (eta.longitude IS DISTINCT FROM geo.x -- !
OR eta.latitude IS DISTINCT FROM geo.y)
甚至可以通過減少要完成的作業(大幅)來解決您的問題。(事實證明,這不是你的情況。
看:
- 我如何(或我可以)在多列上選擇 DISTINCT?
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/446063.html
