首页 > 解决方案 > 过滤 UNION ALL 结果比过滤每个子查询要慢得多

问题描述

我有简单的选择

EXPLAIN (ANALYZE, COSTS, VERBOSE, BUFFERS, FORMAT JSON)
SELECT
  *
FROM
  view_rezervacijos_krepselio_pardavimai
where
  krepselis = '82520963324053795678'

运行缓慢。与https://dba.stackexchange.com/questions/136653/filtering-union-all-result-is-much-slower-than-filtering-each-subquery中的问题完全相同我想知道没有什么我可以做的制作一个接受 krepselis 作为参数的函数。我在https://tatiyants.com/pev/#/plans/new中使用了我的解释https://pastebin.com/zTBWzkW1

private.blt_rezervuota_vieta 的索引:

CREATE INDEX fki_renginys
  ON private.blt_rezervuota_vieta
  USING btree
  (rvt_renginys);

CREATE INDEX fki_rezervuotos_vietos_bilietas
  ON private.blt_rezervuota_vieta
  USING btree
  (rvt_bilietas);

CREATE INDEX idx_blt_rezervuota_vieta__pirkinys_id
  ON private.blt_rezervuota_vieta
  USING btree
  (rvt_pirkinys_id);

CREATE INDEX idx_rezervuota_vieta
  ON private.blt_rezervuota_vieta
  USING btree
  (rvt_renginys, rvt_renginio_data, rvt_renginio_laikas, rvt_sektorius COLLATE pg_catalog."default", rvt_eile COLLATE pg_catalog."default", rvt_vieta COLLATE pg_catalog."default");

CREATE INDEX idx_rvt_seansas
  ON private.blt_rezervuota_vieta
  USING btree
  (rvt_renginys, rvt_renginio_data, rvt_renginio_laikas, rvt_sales_planas);

还有视图本身:

CREATE OR REPLACE VIEW public.view_rezervacijos_krepselio_pardavimai AS 
 SELECT DISTINCT skirtingi_pard.krepselis,
    skirtingi_pard.pardavimo_id
   FROM ( SELECT view_blt_rezervacijos_krepselio_prekes_copy.rkp_krepselis AS krepselis,
            view_blt_rezervacijos_krepselio_prekes_copy.rkp_pardavimas AS pardavimo_id
           FROM private.view_blt_rezervacijos_krepselio_prekes_copy
          WHERE view_blt_rezervacijos_krepselio_prekes_copy.rkp_pardavimas IS NOT NULL
        UNION ALL
         SELECT view_blt_rezervacijos_krepselio_abonementai_copy.rka_krepselis AS krepselis,
            view_blt_rezervacijos_krepselio_abonementai_copy.rka_pardavimas AS pardavimo_id
           FROM private.view_blt_rezervacijos_krepselio_abonementai_copy
          WHERE view_blt_rezervacijos_krepselio_abonementai_copy.rka_pardavimas IS NOT NULL
        UNION ALL
         SELECT view_blt_rezervuota_vieta_copy.rvt_krepselis AS krepselis,
            view_blt_rezervuota_vieta_copy.rvt_pardavimas AS pardavimo_id
           FROM private.view_blt_rezervuota_vieta_copy
          WHERE view_blt_rezervuota_vieta_copy.rvt_pardavimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_avanso_papildymas.rka_krepselis AS krepselis,
            blt_rezervacijos_krepselio_avanso_papildymas.rka_pardavimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_avanso_papildymas
             JOIN b_mokejimai ON b_mokejimai.mok_pardavimas = blt_rezervacijos_krepselio_avanso_papildymas.rka_pardavimas
          WHERE b_mokejimai.mok_budas <> 7
        UNION ALL
         SELECT blt_rezervacijos_krepselio_td_sutartis.ktd_krepselis AS krepselis,
            imoku_pardavimai.pard_id AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_td_sutartis
             JOIN b_td_sutartis ON b_td_sutartis.tds_id = blt_rezervacijos_krepselio_td_sutartis.ktd_sutartis
             JOIN b_pardavimai td_pardavimas ON td_pardavimas.pard_id = b_td_sutartis.tds_pardavimas
             JOIN b_pardavimai imoku_pardavimai ON imoku_pardavimai.pard_susieta = td_pardavimas.pard_susieta
        UNION ALL
         SELECT view_blt_rezervacijos_krepselio_kuponai_paslaugai_copy.kkp_krepselis AS krepselis,
            kuponai_paslaugai.kp_pardavimas AS pardavimo_id
           FROM private.view_blt_rezervacijos_krepselio_kuponai_paslaugai_copy
             JOIN kuponai_paslaugai ON kuponai_paslaugai.kp_numeris::text = view_blt_rezervacijos_krepselio_kuponai_paslaugai_copy.kkp_kupono_numeris::text
          WHERE kuponai_paslaugai.kp_pardavimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_kuponai_sumai.kks_krepselis AS krepselis,
            kuponai_sumai.ks_pardavimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_kuponai_sumai
             JOIN kuponai_sumai ON kuponai_sumai.ks_numeris::text = blt_rezervacijos_krepselio_kuponai_sumai.kks_kuponas::text
          WHERE kuponai_sumai.ks_pardavimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_pakvietimo_naudojimas.rpn_krepselis AS krepselis,
            kuponai_paslaugai.kp_naudojimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_pakvietimo_naudojimas
             JOIN kuponai_paslaugai ON kuponai_paslaugai.kp_numeris::text = blt_rezervacijos_krepselio_pakvietimo_naudojimas.rpn_pakvietimas::text
          WHERE kuponai_paslaugai.kp_naudojimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_krepselis AS krepselis,
            blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_pardavimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_td_plano_keitimas
          WHERE blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_pardavimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_krepselis AS krepselis,
            blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_avanso_papildymo_pardavimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_td_plano_keitimas
          WHERE blt_rezervacijos_krepselio_td_plano_keitimas.rkpk_avanso_papildymo_pardavimas IS NOT NULL
        UNION ALL
         SELECT view_blt_rezervacijos_krepselio_abonemento_keitimas_copy.rkak_krepselis AS krepselis,
            view_blt_rezervacijos_krepselio_abonemento_keitimas_copy.rkak_pardavimas AS pardavimo_id
           FROM private.view_blt_rezervacijos_krepselio_abonemento_keitimas_copy
          WHERE view_blt_rezervacijos_krepselio_abonemento_keitimas_copy.rkak_pardavimas IS NOT NULL
        UNION ALL
         SELECT blt_rezervacijos_krepselio_td_nutraukimai.rkn_krepselis AS krepselis,
            blt_rezervacijos_krepselio_td_nutraukimai.rkn_pardavimas AS pardavimo_id
           FROM private.blt_rezervacijos_krepselio_td_nutraukimai
          WHERE blt_rezervacijos_krepselio_td_nutraukimai.rkn_pardavimas IS NOT NULL) skirtingi_pard;

标签: sqlpostgresql

解决方案


通过将指向 krepselis 的每个联合项转换为相同的数据库类型来解决该问题。


推荐阅读