postgres更新加入慢性能
postgres update with join slow performance
我有以下 tables 并尝试从第二个 table 更新到第一个,似乎需要超过 15 分钟,我当时就把它杀了。
基本上只是试图将一个字段从 table 设置到另一个字段。两个 table 都有大约 250 万行。我们如何优化这个操作?
第一个table:
\d table1
Table "public.fa_market_urunu"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+-----------------------
id | character varying | | not null |
ad | character varying | | |
url | character varying | | |
image_url | character varying | | |
satici_id | character varying | | not null |
satici | character varying | | not null |
category_id | character varying | | |
date_created | timestamp with time zone | | not null | now()
last_updated | timestamp(3) with time zone | | not null | now()
fiyat | double precision | | |
Indexes:
"tbl1_pkey" PRIMARY KEY, btree (id)
"tbl1_satici" UNIQUE, btree (id, satici)
"tbl1_satici_id" UNIQUE, btree (satici, id)
"tbl1_satici_id_last_updated" UNIQUE, btree (satici, id, last_updated)
"tbl1_satici_id_satici_key" UNIQUE CONSTRAINT, btree (satici_id, satici)
"tbl1_satici_last_updated_id" UNIQUE, btree (satici, last_updated, id)
"tbl1_last_updated" btree (last_updated)
"tbl1_satici_category" btree (satici, category_id)
"tbl1_satici_category_last_updated" btree (satici, category_id, last_updated)
"tbl1_satici_last_updated" btree (satici, last_updated)
秒table:
\d table2
Table "public.temp_son_fiyat"
Column | Type | Collation | Nullable | Default
---------+-------------------+-----------+----------+---------
urun_id | character varying | | |
satici | character varying | | |
fiyat | double precision | | |
Indexes:
"ind_u" UNIQUE, btree (urun_id, satici)
我的操作:
UPDATE table1 mu
SET fiyat = fn.fiyat
FROM table2 AS fn
WHERE mu.satici_id = fn.urun_id AND mu.satici = fn.satici;
发生这种情况是因为索引。 postgres 中的每次更新都被视为对该行的重新插入,而不管列是否更新,因此所有索引都会重新计算。为了使其更快,删除索引或交换到新的 table 会起作用(如果可能的话)。
我有以下 tables 并尝试从第二个 table 更新到第一个,似乎需要超过 15 分钟,我当时就把它杀了。
基本上只是试图将一个字段从 table 设置到另一个字段。两个 table 都有大约 250 万行。我们如何优化这个操作?
第一个table:
\d table1
Table "public.fa_market_urunu"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+-----------------------
id | character varying | | not null |
ad | character varying | | |
url | character varying | | |
image_url | character varying | | |
satici_id | character varying | | not null |
satici | character varying | | not null |
category_id | character varying | | |
date_created | timestamp with time zone | | not null | now()
last_updated | timestamp(3) with time zone | | not null | now()
fiyat | double precision | | |
Indexes:
"tbl1_pkey" PRIMARY KEY, btree (id)
"tbl1_satici" UNIQUE, btree (id, satici)
"tbl1_satici_id" UNIQUE, btree (satici, id)
"tbl1_satici_id_last_updated" UNIQUE, btree (satici, id, last_updated)
"tbl1_satici_id_satici_key" UNIQUE CONSTRAINT, btree (satici_id, satici)
"tbl1_satici_last_updated_id" UNIQUE, btree (satici, last_updated, id)
"tbl1_last_updated" btree (last_updated)
"tbl1_satici_category" btree (satici, category_id)
"tbl1_satici_category_last_updated" btree (satici, category_id, last_updated)
"tbl1_satici_last_updated" btree (satici, last_updated)
秒table:
\d table2
Table "public.temp_son_fiyat"
Column | Type | Collation | Nullable | Default
---------+-------------------+-----------+----------+---------
urun_id | character varying | | |
satici | character varying | | |
fiyat | double precision | | |
Indexes:
"ind_u" UNIQUE, btree (urun_id, satici)
我的操作:
UPDATE table1 mu
SET fiyat = fn.fiyat
FROM table2 AS fn
WHERE mu.satici_id = fn.urun_id AND mu.satici = fn.satici;
发生这种情况是因为索引。 postgres 中的每次更新都被视为对该行的重新插入,而不管列是否更新,因此所有索引都会重新计算。为了使其更快,删除索引或交换到新的 table 会起作用(如果可能的话)。