在postgresql中加入非常慢

时间:2018-05-28 13:20:21

标签: postgresql join

我正在尝试加入两个大表(t1​​:4.5mio和t2:100mio。行)并在新表中收集信息。 它需要年龄(> 24小时)。 我不是专家,所以我不知道如何阅读查询计划和优化内容。

这是我的命令:

CREATE table new as
SELECT DISTINCT
    t1.*, t2.publn_nr, t2.publn_nr_original
FROM addresses_googleresponse t1
JOIN patstat2.tls211_pat_publn t2
    ON t1.appln_id = t2.appln_id

t1.appln_idt2.appln_id已编入索引。

查询计划:

Unique  (cost=2335238007.81..2344507241.10 rows=72699869 width=14874)"
  ->  Sort  (cost=2335238007.81..2335419757.48 rows=72699869 width=14874)"
       Sort Key: t1.location_id, t1.id, t1.unformattedaddress, t1.ts, t1.googleresponse, t1.parsegoogleresponsestatus, t1.numresults, t1.formattedaddress, t1.lat, t1.lng, t1.maintype, t1.types, t1.viewportarea, t1.administrative_area_level_1, t1.administr (...)"
       ->  Hash Join  (cost=121.82..11099071.55 rows=72699869 width=14874)"
          Hash Cond: (t1.appln_id = t2.appln_id)"
          ->  Seq Scan on addresses_googleresponse t1  (cost=0.00..8410623.64 rows=52302064 width=14608)"
          ->  Hash  (cost=118.34..118.34 rows=278 width=270)"
                ->  Foreign Scan on tls211_pat_publn t2  (cost=100.00..118.34 rows=278 width=270)"

以下问题的答案:

t1不是临时表,没有(我更改了名称以避免混淆)。如上所述,它在appln_id上有一个索引。表定义:

create table addresses_googleresponse (
id int,
unformattedAddress varchar(500),
ts timestamp,
googleResponse text,
parseGoogleResponseStatus text,
numResults integer,
formattedAddress varchar(500),
lat real,
lng real,
mainType varchar(200),
types text,
viewportArea real,
administrative_area_level_1 varchar(200),
administrative_area_level_2 varchar(200),
administrative_area_level_3 varchar(200),
administrative_area_level_4 varchar(200),
administrative_area_level_5 varchar(200),
airport varchar(200),
country varchar(200),
establishment varchar(200),
floor varchar(200),
locality varchar(200),
natural_feature varchar(200),
neighborhood varchar(200),
park varchar(200),
point_of_interest varchar(200),
post_box varchar(200),
postal_code varchar(200),
postal_code_prefix varchar(200),
postal_code_suffix varchar(200),
postal_town varchar(200),
premise varchar(200),
route varchar(200),
street_address varchar(200),
street_number varchar(200),
sublocality varchar(200),
sublocality_level_1 varchar(200),
sublocality_level_2 varchar(200),
sublocality_level_3 varchar(200),
sublocality_level_4 varchar(200),
sublocality_level_5 varchar(200),
subpremise varchar(200),
ward varchar(200),
data_source varchar(2),
location_id int,
appln_id int
);

CREATE TABLE patstat.tls211_pat_publn
(
pat_publn_id integer NOT NULL DEFAULT 0,
publn_auth character(2) NOT NULL DEFAULT ''::bpchar,
publn_nr character varying(15) NOT NULL DEFAULT ''::character varying,
publn_nr_original character varying(100) NOT NULL DEFAULT ''::characte varying, 
publn_kind character(2) NOT NULL DEFAULT ''::bpchar,
appln_id integer NOT NULL DEFAULT 0,
publn_date date NOT NULL DEFAULT '9999-12-31'::date,
publn_lg character(2) NOT NULL DEFAULT ''::bpchar,
publn_first_grant smallint DEFAULT (0)::smallint,
publn_claims smallint NOT NULL DEFAULT (0)::smallint,
CONSTRAINT tls211_pat_publn_pkey PRIMARY KEY (pat_publn_id)
)

目标是根据publn_nr两个表共享,将publn_nr_originalappln_id添加到t1中的其他列。

update t1.publn_nrt1.publn_nr_original选项/更快(将列添加到t1后?

我现在正在尝试没有distinct,但它已经运行了几个小时。

Postgresql版本9.6.5。

1 个答案:

答案 0 :(得分:0)

要获得明确答案,需要EXPLAIN (ANALYZE, BUFFERS)输出。

但是,如果PostgreSQL的估计是正确的,那么你的问题是DISTINCT:PostgreSQL必须对72699869行进行排序以删除重复项,这就是花费时间的地方。请参阅cost估算值。

如果您可以摆脱DISTINCT,请执行此操作。如果没有,请尝试启动work_mem并查看它是否使处理速度更快。