2016-12-04 78 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的更高限制。