简单选择在PostgreSQL中进行优化

时间:2017-05-31 14:11:25

标签: sql postgresql join create-table

我有以下查询,我想优化它,执行时间是4秒,行数是122,928,但表中没有任何链接。

有没有办法优化这个?我需要相同数量的行,但执行时间需要大幅下降。

select dc.cddocument, us.cduser
from dcdocument dc, aduser us
 WHERE  (dc.FGUSECATACCESSROLE <> 1 OR dc.FGUSECATACCESSROLE IS NULL);

查询计划

teste20=# explain analyze select dc.cddocument, us.cduser from dcdocument dc, aduser us WHERE  (dc.FGUSECATACCESSROLE <> 1 OR dc.FGUSECATACCESSROLE IS NULL);
                                                           QUERY PLAN                                            
---------------------------------------------------------------------------------
     Nested Loop  (cost=0.00..1584.32 rows=124110 width=8) (actual time=0.062..23.679 rows=122928 loops=1)
       ->  Seq Scan on aduser us  (cost=0.00..19.91 rows=591 width=4) (actual time=0.029..0.190 rows=591 loops=1)
       ->  Materialize  (cost=0.00..13.56 rows=210 width=4) (actual time=0.000..0.012 rows=208 loops=591)
             ->  Seq Scan on dcdocument dc  (cost=0.00..12.51 rows=210 width=4) (actual time=0.024..0.308 rows=208 loops=1)
                   Filter: ((fgusecataccessrole <> 1) OR (fgusecataccessrole IS NULL))
                   Rows Removed by Filter: 393
     Planning time: 0.474 ms
     Execution time: 27.183 ms
    (8 registros)

查询计划不会显示执行的实际时间。

CREATE TABLE dcdocument

CREATE TABLE public.dcdocument
(
    cddocument integer NOT NULL,
    cdcategory integer,
    dtdocument date,
    fgstatus integer,
    dssummary text COLLATE pg_catalog."default",
    nmtitle character varying(255) COLLATE pg_catalog."default",
    nmauthor character varying(255) COLLATE pg_catalog."default",
    iddocument character varying(50) COLLATE pg_catalog."default",
    dsdoccancel text COLLATE pg_catalog."default",
    fgusecataccessrole integer,
    cdcreatedby integer,
    nrhits integer,
    dtinsert date,
    dtupdate date,
    nmuserupd character varying(255) COLLATE pg_catalog."default",
    dtvalidity date,
    qtvalidity integer,
    fgtypevalid integer,
    cdprod integer,
    cdapprov integer,
    cdtemparchival integer,
    cdfavorite integer,
    fgoldstatus integer,
    CONSTRAINT pkdcdocument PRIMARY KEY (cddocument),
    CONSTRAINT fkdocumcdcreatedby FOREIGN KEY (cdcreatedby)
        REFERENCES public.aduser (cduser) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE public.dcdocument
    OWNER to postgres;
CREATE INDEX "TESTES"
    ON public.dcdocument USING btree
    (cddocument, fgusecataccessrole)
    TABLESPACE pg_default;
CREATE INDEX seixdoccataccessrole
    ON public.dcdocument USING btree
    (fgusecataccessrole)
    TABLESPACE pg_default;
CREATE INDEX seixdoccdcategory
    ON public.dcdocument USING btree
    (cdcategory)
    TABLESPACE pg_default;
CREATE INDEX seixdocumcdcreated
    ON public.dcdocument USING btree
    (cdcreatedby)
    TABLESPACE pg_default;
CREATE INDEX seixdocumentapprov
    ON public.dcdocument USING btree
    (cdprod, cdapprov)
    TABLESPACE pg_default;
CREATE INDEX seixdocumentfavori
    ON public.dcdocument USING btree
    (cdfavorite)
    TABLESPACE pg_default;
CREATE INDEX seixdocumentstatus
    ON public.dcdocument USING btree
    (fgstatus)
    TABLESPACE pg_default;
CREATE INDEX seixdocumtemparchi
    ON public.dcdocument USING btree
    (cdtemparchival)
    TABLESPACE pg_default;

CREATE TABLE aduser

CREATE TABLE public.aduser
(
    cduser integer NOT NULL,
    idlogin character varying(50) COLLATE pg_catalog."default",
    iduser character varying(50) COLLATE pg_catalog."default",
    nmuser character varying(255) COLLATE pg_catalog."default",
    idpassword character varying(50) COLLATE pg_catalog."default",
    dsuseremail text COLLATE pg_catalog."default",
    fglanguage integer,
    fguserenabled integer,
    cdmailserver integer,
    cdleader integer,
    dtinsert date,
    dtupdate date,
    nmuserupd character varying(255) COLLATE pg_catalog."default",
    idphone character varying(50) COLLATE pg_catalog."default",
    dsuser text COLLATE pg_catalog."default",
    nmdomainuid character varying(255) COLLATE pg_catalog."default",
    nmcertserialnum character varying(255) COLLATE pg_catalog."default",
    flpublickey bytea,
    fgnotice integer,
    fgstatuslogin integer,
    flphoto bytea,
    fgaccessrestrict integer,
    fgalterpassword integer,
    nmviewmodules character varying(255) COLLATE pg_catalog."default",
    idpasswordvalid character varying(50) COLLATE pg_catalog."default",
    nmuseremail character varying(255) COLLATE pg_catalog."default",
    fgtheme integer,
    fghomepage integer,
    dsurlhomepage text COLLATE pg_catalog."default",
    cddashboard integer,
    cddashboardtab integer,
    fgdashdoshare integer,
    dtrequestrstpsw date,
    idhashpassword character varying(50) COLLATE pg_catalog."default",
    cdlastlicense integer,
    fgpwdversion integer,
    cdcustomization integer,
    nmhashlastsession character varying(255) COLLATE pg_catalog."default",
    fgtransfped integer,
    cdtransfpedto integer,
    fgcontactenable integer,
    fgcontactpopup integer,
    cdfavorite integer,
    fgedittoolbar integer,
    fgeditgrid integer,
    nmphotopath character varying(255) COLLATE pg_catalog."default",
    dtbirthday date,
    CONSTRAINT pkaduser PRIMARY KEY (cduser),
    CONSTRAINT fk__aduser__cdtransf__56764864 FOREIGN KEY (cdtransfpedto)
        REFERENCES public.aduser (cduser) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT fk_userleader FOREIGN KEY (cdleader)
        REFERENCES public.aduser (cduser) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.aduser
    OWNER to postgres;
CREATE INDEX "TESTE2"
    ON public.aduser USING btree
    (cduser)
    TABLESPACE pg_default;
CREATE INDEX seixcdleader
    ON public.aduser USING btree
    (cdleader)
    TABLESPACE pg_default;
CREATE INDEX seixusercdmailserv
    ON public.aduser USING btree
    (cdmailserver)
    TABLESPACE pg_default;
CREATE INDEX seixusercdtransfpedto
    ON public.aduser USING btree
    (cdtransfpedto)
    TABLESPACE pg_default;
CREATE INDEX seixuserenabled
    ON public.aduser USING btree
    (fguserenabled)
    TABLESPACE pg_default;
CREATE INDEX seixuserfglanguage
    ON public.aduser USING btree
    (fglanguage)
    TABLESPACE pg_default;
CREATE INDEX seixusergnfavorite
    ON public.aduser USING btree
    (cdfavorite)
    TABLESPACE pg_default;
CREATE INDEX seixuseridlogin
    ON public.aduser USING btree
    (idlogin COLLATE pg_catalog."default")
    TABLESPACE pg_default;
CREATE INDEX seixusernmdomainuid
    ON public.aduser USING btree
    (nmdomainuid COLLATE pg_catalog."default")
    TABLESPACE pg_default;
CREATE INDEX seixusernmfgencdus
    ON public.aduser USING btree
    (nmuser COLLATE pg_catalog."default", iduser COLLATE pg_catalog."default", cduser, fguserenabled)
    TABLESPACE pg_default;

1 个答案:

答案 0 :(得分:0)

您的查询已经以最佳方式执行,并且在27毫秒内完成。

有两件事可能有助于解释您观察到的问题:

  1. 您在两个表之间执行交叉连接,因为没有连接它们的WHERE条件,即aduser中的每一行都与{{1}中的每一行组合符合条件。

    导致208 * 591 = 122928个结果行,这可能不是你想要的。

  2. 您必须使用像pgAdmin这样的客户端,它需要很长时间才能显示从查询返回的许多结果行。

  3. 解决方案可能是在dcdocumentWHERE子句中添加缺失的条件。