2016-12-04 81 views
0

在同一个数据库中有两个模式 - oatarchival和oat 模式彼此完全相似。如何让这个删除查询在postgres上运行得更快?

这里是我跑步,它走的是时间很多

DELETE FROM oat.oat_user_tag_verification 
    using oatarchival.oat_user_tag_verification outv, oat.fp_archived f 
    WHERE outv.tag_id = f.tag_id and f.is_archived=false 
    and oat_user_tag_verification.user_id = outv.user_id and 
    oat_user_tag_verification.tag_id = outv.tag_id and 
    oat_user_tag_verification.verification_status = outv.verification_status 
    and oat_user_tag_verification.created_at=outv.created_at 
    and oat_user_tag_verification.updated_at=outv.updated_at 

这里是详细解释了这个查询的查询 -

"Delete on oat.oat_user_tag_verification (cost=14989031.30..16227081.67 rows=1 width=18)" 
" -> Nested Loop (cost=14989031.30..16227081.67 rows=1 width=18)" 
"  Output: oat_user_tag_verification.ctid, outv.ctid, f.ctid" 
"  Join Filter: (outv.tag_id = f.tag_id)" 
"  -> Merge Join (cost=14989031.30..16021422.32 rows=1 width=28)" 
"    Output: oat_user_tag_verification.ctid, oat_user_tag_verification.tag_id, outv.ctid, outv.tag_id" 
"    Merge Cond: ((oat_user_tag_verification.tag_id = outv.tag_id) AND (oat_user_tag_verification.user_id = outv.user_id) AND (oat_user_tag_verification.verification_status = outv.verification_status) AND (oat_user_tag_verification.created_at = ou (...)" 
"    -> Sort (cost=13223314.06..13368102.38 rows=57915328 width=38)" 
"     Output: oat_user_tag_verification.ctid, oat_user_tag_verification.user_id, oat_user_tag_verification.tag_id, oat_user_tag_verification.verification_status, oat_user_tag_verification.created_at, oat_user_tag_verification.updated_at" 
"     Sort Key: oat_user_tag_verification.tag_id, oat_user_tag_verification.user_id, oat_user_tag_verification.verification_status, oat_user_tag_verification.created_at, oat_user_tag_verification.updated_at" 
"     -> Seq Scan on oat.oat_user_tag_verification (cost=0.00..1005001.28 rows=57915328 width=38)" 
"       Output: oat_user_tag_verification.ctid, oat_user_tag_verification.user_id, oat_user_tag_verification.tag_id, oat_user_tag_verification.verification_status, oat_user_tag_verification.created_at, oat_user_tag_verification.updated_at" 
"    -> Materialize (cost=1765717.25..1812477.56 rows=9352062 width=38)" 
"     Output: outv.ctid, outv.tag_id, outv.user_id, outv.verification_status, outv.created_at, outv.updated_at" 
"     -> Sort (cost=1765717.25..1789097.40 rows=9352062 width=38)" 
"       Output: outv.ctid, outv.tag_id, outv.user_id, outv.verification_status, outv.created_at, outv.updated_at" 
"       Sort Key: outv.tag_id, outv.user_id, outv.verification_status, outv.created_at, outv.updated_at" 
"       -> Seq Scan on oatarchival.oat_user_tag_verification outv (cost=0.00..171454.62 rows=9352062 width=38)" 
"        Output: outv.ctid, outv.tag_id, outv.user_id, outv.verification_status, outv.created_at, outv.updated_at" 
"  -> Seq Scan on oat.fp_archived f (cost=0.00..191863.83 rows=1103642 width=14)" 
"    Output: f.ctid, f.tag_id" 
"    Filter: (NOT f.is_archived)" 

此处是创建表结构所有表涉及:

表fp_archived:

CREATE TABLE fp_archived 
(
    tag_id bigint NOT NULL, 
    detection_url text, 
    image_id bigint NOT NULL, 
    pixel_x smallint NOT NULL, 
    camera_num smallint NOT NULL, 
    pixel_y smallint NOT NULL, 
    width smallint NOT NULL, 
    height smallint NOT NULL, 
    is_archived boolean DEFAULT false, 
    id bigint NOT NULL DEFAULT nextval('fp_archived_seq'::regclass), 
    drive_id character varying(255), 
    CONSTRAINT fp_archived_pkey PRIMARY KEY (id) 
) 

表oat_user_tag_verification:

CREATE TABLE oatarchival.oat_user_tag_verification 
(
    user_id integer NOT NULL, 
    tag_id bigint NOT NULL, 
    verification_status integer NOT NULL, 
    created_at timestamp without time zone NOT NULL DEFAULT now(), 
    updated_at timestamp without time zone DEFAULT now(), 
    CONSTRAINT oat_user_tag_verification_pkey PRIMARY KEY (user_id, tag_id, verification_status, created_at), 
    CONSTRAINT oat_user_tag_verification_tag_id_fkey FOREIGN KEY (tag_id) 
     REFERENCES oatarchival.oat_tags (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT oat_user_tag_verification_user_id_fkey FOREIGN KEY (user_id) 
     REFERENCES oatarchival.oat_users (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT oat_user_tag_verification_verification_status_fkey FOREIGN KEY (verification_status) 
     REFERENCES oatarchival.oat_tag_verification_status (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

删除查询中几个小时运行。我怎样才能优化它? 我应该为这个查询创建哪些索引变得更快?

+0

您应该为该字段创建索引,包括 –

+0

您能指导我应该创建哪个索引吗? – Tisha

+0

对不起,错误的链接。检查这里的一些提示MySQL索引[** TIPS **](http://mysql.rjweb.org/doc.php/index_cookbook_mysql) –

回答

1

根据您EXPLAIN输出(不幸的是你没有跑EXPLAIN (ANALYZE)),我建议以下指标:

CREATE INDEX ON oatarchival.oat_user_tag_verification(
    ctid, 
    tag_id, 
    user_id, 
    verification_status, 
    created_at, 
    updated_at 
); 

CREATE INDEX ON oat.oat_user_tag_verification(
    tag_id, 
    user_id, 
    verification_status, 
    created_at, 
    updated_at 
); 

这些可以合并帮助加盟。

然后,我创建了以下指标:

CREATE INDEX ON oat.fp_archived(tag_id); 

这将加快嵌套循环连接。

不知道这是否是运行查询的最佳方式,但它是一个起点。

+0

请帮我画一下我可以改进这个问题以帮助解除我的问题禁令? – Tisha

+0

“问题禁令”是什么意思? –

+0

禁止在提问上的计算器:( – Tisha

1

一个暗示不良经验 - 尝试摆脱会议的work_mem设置。我在新的PostgreSQL 9.6上遇到了令人难以置信的查询成本的类似问题,并且它只需要work_mem的更高限制。