我正在尝试查询另一个软件的数据库,所以我无法控制索引,函数等。我有只读访问权限,所以我不相信我甚至可以创建一个临时表。我只是无法理解为什么会有差异。
这是我的基本查询:
WITH vCriteria AS (
SELECT vSub.visit_id, vd.vdiag_diag from visit vSUB
JOIN insurance_company_table1 inscomp1 ON inscomp1.inscomp1_comp = vSub.visit_ins
and inscomp1.inscomp1_arid = vSub.visit_arid
JOIN da152 da ON da.da152_arid = vSub.visit_arid
LEFT JOIN insurance1 i ON i.is1_num = vSub.visit_id AND i.is1_ins_full = vSub.visit_ins
LEFT JOIN visit_diagnosis vd ON vd.vdiag_visit_key = vSub.visit_id
WHERE vSub.visit_mr_fdt
BETWEEN (now() - 50 * INTERVAL '1 day') AND (now() + 10 * INTERVAL '1 day')
AND NULLIF (vSub.visit_disch_date, '0001-01-01' ::date) IS NOT NULL
AND Now() >=(vSub.visit_disch_date + inscomp1.inscomp1_lagdays * INTERVAL '1 day')
AND vSub.visit_servicecd_key ~ '^[0-9]+$|[FHJbKkN\\+]' = false
AND LEFT (vSub.visit_id, 1) NOT IN ('F', 'P', 'J')
AND NULLIF (i.is1_bill_dt, '0001-01-01' ::date) IS NULL
AND vSub.visit_disch_date <= da.da152_chgdt
)
Select vCriteria.* from vCriteria
它在609 ms内执行
我添加1个连接,需要更长的时间: LEFT JOIN visit_diagnosis vd ON vd.vdiag_visit_key = vSub.visit_id
WITH vCriteria AS (
SELECT vSub.visit_id, vd.vdiag_diag from visit vSUB
JOIN insurance_company_table1 inscomp1 ON inscomp1.inscomp1_comp = vSub.visit_ins
and inscomp1.inscomp1_arid = vSub.visit_arid
JOIN da152 da ON da.da152_arid = vSub.visit_arid
LEFT JOIN insurance1 i ON i.is1_num = vSub.visit_id AND i.is1_ins_full = vSub.visit_ins
LEFT JOIN visit_diagnosis vd ON vd.vdiag_visit_key = vSub.visit_id
WHERE vSub.visit_mr_fdt
BETWEEN (now() - 50 * INTERVAL '1 day') AND (now() + 10 * INTERVAL '1 day')
AND NULLIF (vSub.visit_disch_date, '0001-01-01' ::date) IS NOT NULL
AND Now() >=(vSub.visit_disch_date + inscomp1.inscomp1_lagdays * INTERVAL '1 day')
AND vSub.visit_servicecd_key ~ '^[0-9]+$|[FHJbKkN\\+]' = false
AND LEFT (vSub.visit_id, 1) NOT IN ('F', 'P', 'J')
AND NULLIF (i.is1_bill_dt, '0001-01-01' ::date) IS NULL
AND vSub.visit_disch_date <= da.da152_chgdt
)
Select vCriteria.* from vCriteria
执行
需要13秒因此,上面的查询非常简化,这里是我试过的例子。 如果我做这样的事情:
SELECT t.id_field from table t
JOIN . . .
JOIN . . .
WHERE <10 rows of filtering criteria>
它在766毫秒内执行并带回411条记录
当我单独运行此查询时:
select t.id_field, t2.field1 from table t
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
WHERE t.id_field in ( <I list out the varchar(8) values here from first query> )
它在3.031秒执行
但是,如果我尝试将查询放在一起,就像这样
select t.id_field, t2.field1 from table t
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
WHERE t.id_field in (
SELECT t.id_field from table t
JOIN . . .
JOIN . . .
WHERE <10 rows of filtering criteria>
)
需要19.406秒
我尝试过如下的WITH语句:
WITH vt AS (
SELECT t.id_field from table t
JOIN . . .
JOIN . . .
WHERE <10 rows of filtering criteria>
)
select vt.id_field, t2.field1 from vt
LEFT JOIN table2 t2 ON t2.t_id_field = vt.id_field
它在12秒内执行
我试过这个:
select t.id_field, t2.field1 from (
SELECT tsub.id_field from table tsub
JOIN . . .
JOIN . . .
WHERE <10 rows of filtering criteria>
) t
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
在12.750秒内执行
另一种尝试就是:
SELECT t.id_field, t2.field1 from table t
JOIN . . .
JOIN . . .
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
WHERE <10 rows of filtering criteria>
执行于12.813秒
关于如何让它达到至少3秒的任何想法,就像上面那个我手动输入值的那个?
这是执行计划
QUERY PLAN
Nested Loop Left Join (cost=109243.37..119017.89 rows=1 width=83)
CTE vc
-> Nested Loop (cost=14871.86..109243.37 rows=1 width=7)
-> Nested Loop (cost=14871.86..109242.01 rows=4 width=24)
Join Filter: ((vsub.visit_disch_date <= da.da152_chgdt) AND (vsub.visit_arid = da.da152_arid))
-> Index Scan using da152_pkey on da152 da (cost=0.00..10.40 rows=4 width=9)
-> Materialize (cost=14871.86..109230.80 rows=12 width=19)
-> Hash Right Join (cost=14871.86..109230.74 rows=12 width=19)
Hash Cond: (((i.is1_num)::text = (vsub.visit_id)::text) AND ((i.is1_ins_full)::text = (vsub.visit_ins)::text))
Filter: (NULLIF(i.is1_bill_dt, '0001-01-01'::date) IS NULL)
-> Seq Scan on insurance1 i (cost=0.00..90993.64 rows=336264 width=14)
-> Hash (cost=14837.16..14837.16 rows=2313 width=19)
-> Seq Scan on visit vsub (cost=0.00..14837.16 rows=2313 width=19)
Filter: ((NULLIF(visit_disch_date, '0001-01-01'::date) IS NOT NULL) AND ((visit_servicecd_key)::text !~ '^[0-9]+$|[FHJbKkN\\+]'::text) AND ("left"((visit_id)::text, 1) <> ALL ('{F,P,J}'::text[])) AND (visit_mr_fdt >= (now() - '50 days'::interval)) AND (visit_mr_fdt <= (now() + '10 days'::interval)))
-> Index Scan using inscomp1_pkey on insurance_company_table1 inscomp1 (cost=0.00..0.33 rows=1 width=11)
Index Cond: ((inscomp1_arid = vsub.visit_arid) AND ((inscomp1_comp)::text = (vsub.visit_ins)::text))
Filter: (now() >= (vsub.visit_disch_date + ((inscomp1_lagdays)::double precision * '1 day'::interval)))
-> CTE Scan on vc (cost=0.00..0.02 rows=1 width=12)
-> Index Scan using vdiag_pkey on visit_diagnosis vd (cost=0.00..9774.48 rows=1 width=71)
Index Cond: ((vdiag_visit_key)::text = (vc.visit_id)::text)
Filter: ((vdiag_type)::text = 'A'::text)
和解释(分析,详细)(以“与上面的”查询示例“)
QUERY PLAN
Nested Loop Left Join (cost=109243.36..119017.87 rows=1 width=83) (actual time=418.062..13796.260 rows=414 loops=1)
Output: vc.visit_id, vd.vdiag_visit_key, vd.vdiag_arxseq, vd.vdiag_element, vd.vdiag_type, vd.vdiag_date, vd.vdiag_diag, vd.vdiag_arid
CTE vc
-> Nested Loop (cost=14871.84..109243.36 rows=1 width=7) (actual time=404.477..1006.518 rows=414 loops=1)
Output: vsub.visit_id
-> Nested Loop (cost=14871.84..109242.00 rows=4 width=24) (actual time=404.432..990.137 rows=418 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date, da.da152_arid
Join Filter: ((vsub.visit_disch_date <= da.da152_chgdt) AND (vsub.visit_arid = da.da152_arid))
Rows Removed by Join Filter: 1374
-> Index Scan using da152_pkey on public.da152 da (cost=0.00..10.40 rows=4 width=9) (actual time=0.004..0.017 rows=4 loops=1)
Output: da.da152_rel_file_key_num, da.da152_contrl, da.da152_rcdt, da.da152_chgdt, da.da152_ar_rev, da.da152_ar_rc, da.da152_ar_rcar, da.da152_unpost, da.da152_lrun, da.da152_ar_month, da.da152_insdt, da.da152_otc_rcdt, da.da152_sum_rev, da.da152_sum_rc, da.da152_sum_rcar, da.da152_begbal, da.da152_netar, da.da152_arend, da.da152_eomtrial, da.da152_rc_da, da.da152_rc_amt_otc, da.da152_rc_amt_cp, da.da152_chg_thru, da.da152_ar_ldom, da.da152_csnum, da.da152_sec_e_bill, da.da152_uform, da.da152_jform, da.da152_rate, da.da152_contract_bill, da.da152_up_front, da.da152_bad_debt, da.da152_pat_refund, da.da152_2cnd_ins, da.da152_pat_type1, da.da152_pat_type2, da.da152_pat_srvcd1_old, da.da152_pat_srvcd2_old, da.da152_wo_colcd1, da.da152_wo_alpha1s, da.da152_wo_alpha1e, da.da152_wo_colcd2, da.da152_wo_alpha2s, da.da152_wo_alpha2e, da.da152_wo_colcd3, da.da152_wo_alpha3s, da.da152_wo_alpha3e, da.da152_ins_prim, da.da152_tic_xfc1, da.da152_tic_xfc2, da.da152_ins_fc, da.da152_wo_sitnum, da.da152_wo_sit_cd, da.da152_ins2dt, da.da152_multicoqual, da.da152_multicoid, da.da152_multicodir, da.da152_multicoglnum, da.da152_pat_srvcd1, da.da152_pat_srvcd2, da.da152_adchg, da.da152_adchg_var, da.da152_month_closedt, da.da152_pat_colcd, da.da152_nonaracct, da.da152_isfup_days, da.da152_arid
-> Materialize (cost=14871.84..109230.79 rows=12 width=19) (actual time=101.103..246.563 rows=448 loops=4)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
-> Hash Right Join (cost=14871.84..109230.73 rows=12 width=19) (actual time=404.408..983.328 rows=448 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Hash Cond: (((i.is1_num)::text = (vsub.visit_id)::text) AND ((i.is1_ins_full)::text = (vsub.visit_ins)::text))
Filter: (NULLIF(i.is1_bill_dt, '0001-01-01'::date) IS NULL)
Rows Removed by Filter: 2018
-> Seq Scan on public.insurance1 i (cost=0.00..90993.64 rows=336264 width=14) (actual time=0.002..284.366 rows=341073 loops=1)
Output: i.is1_num, i.is1_ins_full, i.is1_set, i.is1_prim, i.is1_stay, i.is1_direct, i.is1_admit, i.is1_disc, i.is1_from, i.is1_to, i.is1_app_sent, i.is1_app_rec, i.is1_gen_dt, i.is1_ck_dt, i.is1_contract_old, i.is1_bill_dt, i.is1_pd_dt1, i.is1_pd_amt1, i.is1_pd_dt2, i.is1_pd_amt2, i.is1_pd_dt3, i.is1_pd_amt3, i.is1_pd_status, i.is1_med_ness, i.is1_bl_furn, i.is1_bl_rep, i.is1_bl_n_rep, i.is1_bl_rate, i.is1_bl_chg, i.is1_bl_non, i.is1_coamt, i.is1_expay, i.is1_semi_rate, i.is1_diem, i.is1_cd, i.is1_typrm, i.is1_qty, i.is1_chg, i.is1_non, i.is1_opcd, i.is1_opdate, i.is1_opdesc, i.is1_opchg, i.is1_opphy, i.is1_totchg, i.is1_totnon, i.is1_maxlines, i.is1_totlines, i.is1_apc_sw, i.is1_eapc_reim, i.is1_eapc_copay, i.is1_eapc_contr, i.is1_eapc_ded, i.is1_eapc_outlr, i.is1_aapc_reim, i.is1_aapc_copay, i.is1_aapc_contr, i.is1_aapc_ded, i.is1_aapc_outlr, i.is1_mr_okayed, i.is1_mr_ok_init, i.is1_a_ded, i.is1_dayfull, i.is1_dayco, i.is1_daylife, i.is1_bl_ded, i.is1_bl_d_amt, i.is1_contr2, i.is1_copay, i.is1_colim, i.is1_covrmrate, i.is1_lifeused, i.is1_covdays, i.is1_nondays, i.is1_co_used, i.is1_typary, i.is1_effdt, i.is1_covrate, i.is1_endcare, i.is1_drg, i.is1_p_name, i.is1_birth, i.is1_print, i.is1_mndays, i.is1_reim_amt, i.is1_elecbill, i.is1_elecdate, i.is1_ppscode, i.is1_psrocode, i.is1_typebill, i.is1_new_op_medicare, i.is1_netreim, i.is1_serv, i.is1_printcross, i.is1_crossdate, i.is1_filetype, i.is1_releaseinfo, i.is1_pdtype1, i.is1_pdtype2, i.is1_pdtype3, i.is1_coins, i.is1_otprim, i.is1_otins, i.is1_otset, i.is1_coveragesetby, i.is1_covcalctype, i.is1_covverified, i.is1_netcalc, i.is1_orig_expay, i.is1_orig_bl_d_amt, i.is1_orig_coamt, i.is1_orig_a_ded, i.is1_orig_drg, i.is1_orig_covdays, i.is1_excrep, i.is1_exccov, i.is1_genviaautocl, i.is1_autobill, i.is1_formver, i.is1_contract, i.is1_origin, i.is1_covgoverride, i.is1_covglogname, i.is1_covgcsnum, i.is1_excchgs, i.is1_arid, i.is1_drg_icd10
-> Hash (cost=14837.16..14837.16 rows=2312 width=19) (actual time=394.738..394.738 rows=2416 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Buckets: 1024 Batches: 1 Memory Usage: 123kB
-> Seq Scan on public.visit vsub (cost=0.00..14837.16 rows=2312 width=19) (actual time=0.097..391.839 rows=2416 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Filter: ((NULLIF(vsub.visit_disch_date, '0001-01-01'::date) IS NOT NULL) AND ((vsub.visit_servicecd_key)::text !~ '^[0-9]+$|[FHJbKkN\\+]'::text) AND ("left"((vsub.visit_id)::text, 1) <> ALL ('{F,P,J}'::text[])) AND (vsub.visit_mr_fdt >= (now() - '50 days'::interval)) AND (vsub.visit_mr_fdt <= (now() + '10 days'::interval)))
Rows Removed by Filter: 201579
-> Index Scan using inscomp1_pkey on public.insurance_company_table1 inscomp1 (cost=0.00..0.33 rows=1 width=11) (actual time=0.029..0.031 rows=1 loops=418)
Output: inscomp1.inscomp1_comp, inscomp1.inscomp1_name, inscomp1.inscomp1_addr1, inscomp1.inscomp1_addr2, inscomp1.inscomp1_city, inscomp1.inscomp1_state, inscomp1.inscomp1_zip, inscomp1.inscomp1_form, inscomp1.inscomp1_jour, inscomp1.inscomp1_prov, inscomp1.inscomp1_typebill, inscomp1.inscomp1_perdiem, inscomp1.inscomp1_diemdt, inscomp1.inscomp1_priordiem, inscomp1.inscomp1_pcused, inscomp1.inscomp1_phybillsw, inscomp1.inscomp1_approval, inscomp1.inscomp1_psro, inscomp1.inscomp1_ask_reim, inscomp1.inscomp1_reject_days, inscomp1.inscomp1_contrgl, inscomp1.inscomp1_othargl, inscomp1.inscomp1_auto_ip, inscomp1.inscomp1_auto_op, inscomp1.inscomp1_prirate, inscomp1.inscomp1_secrate, inscomp1.inscomp1_lagdays, inscomp1.inscomp1_mul1500, inscomp1.inscomp1_waitfin, inscomp1.inscomp1_opsum, inscomp1.inscomp1_write_off, inscomp1.inscomp1_transmit, inscomp1.inscomp1_detail_bl, inscomp1.inscomp1_provname, inscomp1.inscomp1_provaddr1, inscomp1.inscomp1_provaddr2, inscomp1.inscomp1_provcity, inscomp1.inscomp1_provst, inscomp1.inscomp1_provzip, inscomp1.inscomp1_cont_perc, inscomp1.inscomp1_drg_str, inscomp1.inscomp1_drg_acps, inscomp1.inscomp1_drg_dt, inscomp1.inscomp1_ub_loc2, inscomp1.inscomp1_sub_id, inscomp1.inscomp1_bcno, inscomp1.inscomp1_taxno, inscomp1.inscomp1_mcareno, inscomp1.inscomp1_mcaidno, inscomp1.inscomp1_signature, inscomp1.inscomp1_prov2, inscomp1.inscomp1_allpay, inscomp1.inscomp1_discrate, inscomp1.inscomp1_discdt, inscomp1.inscomp1_discrate2, inscomp1.inscomp1_sumitem, inscomp1.inscomp1_bank_plan, inscomp1.inscomp1_phy_1500, inscomp1.inscomp1_labmc, inscomp1.inscomp1_orer_comb, inscomp1.inscomp1_phybillex, inscomp1.inscomp1_net_reim, inscomp1.inscomp1_ask_drg, inscomp1.inscomp1_provphone, inscomp1.inscomp1_drggroup, inscomp1.inscomp1_phyins, inscomp1.inscomp1_phyub82, inscomp1.inscomp1_mnxsnf, inscomp1.inscomp1_srcpmtcde, inscomp1.inscomp1_provname2, inscomp1.inscomp1_coll_id, inscomp1.inscomp1_diagptr, inscomp1.inscomp1_tax, inscomp1.inscomp1_type_desc, inscomp1.inscomp1_revcode, inscomp1.inscomp1_arid
Index Cond: ((inscomp1.inscomp1_arid = vsub.visit_arid) AND ((inscomp1.inscomp1_comp)::text = (vsub.visit_ins)::text))
Filter: (now() >= (vsub.visit_disch_date + ((inscomp1.inscomp1_lagdays)::double precision * '1 day'::interval)))
-> CTE Scan on vc (cost=0.00..0.02 rows=1 width=12) (actual time=404.481..1008.180 rows=414 loops=1)
Output: vc.visit_id
-> Index Scan using vdiag_pkey on public.visit_diagnosis vd (cost=0.00..9774.48 rows=1 width=71) (actual time=14.246..30.882 rows=1 loops=414)
Output: vd.vdiag_visit_key, vd.vdiag_arxseq, vd.vdiag_element, vd.vdiag_type, vd.vdiag_date, vd.vdiag_diag, vd.vdiag_arid
Index Cond: ((vd.vdiag_visit_key)::text = (vc.visit_id)::text)
Filter: ((vd.vdiag_type)::text = 'A'::text)
Rows Removed by Filter: 1
Total runtime: 13796.881 ms
解释(分析,VERBOSE)只是为了获得要去的MILLISECONDS
QUERY PLAN
Nested Loop (cost=14871.84..109244.42 rows=1 width=7) (actual time=403.659..985.167 rows=432 loops=1)
Output: vsub.visit_id
-> Nested Loop (cost=14871.84..109243.06 rows=4 width=24) (actual time=403.618..980.483 rows=441 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date, da.da152_arid
Join Filter: ((vsub.visit_disch_date <= da.da152_chgdt) AND (vsub.visit_arid = da.da152_arid))
Rows Removed by Join Filter: 1351
-> Index Scan using da152_pkey on public.da152 da (cost=0.00..10.40 rows=4 width=9) (actual time=0.004..0.014 rows=4 loops=1)
Output: da.da152_rel_file_key_num, da.da152_contrl, da.da152_rcdt, da.da152_chgdt, da.da152_ar_rev, da.da152_ar_rc, da.da152_ar_rcar, da.da152_unpost, da.da152_lrun, da.da152_ar_month, da.da152_insdt, da.da152_otc_rcdt, da.da152_sum_rev, da.da152_sum_rc, da.da152_sum_rcar, da.da152_begbal, da.da152_netar, da.da152_arend, da.da152_eomtrial, da.da152_rc_da, da.da152_rc_amt_otc, da.da152_rc_amt_cp, da.da152_chg_thru, da.da152_ar_ldom, da.da152_csnum, da.da152_sec_e_bill, da.da152_uform, da.da152_jform, da.da152_rate, da.da152_contract_bill, da.da152_up_front, da.da152_bad_debt, da.da152_pat_refund, da.da152_2cnd_ins, da.da152_pat_type1, da.da152_pat_type2, da.da152_pat_srvcd1_old, da.da152_pat_srvcd2_old, da.da152_wo_colcd1, da.da152_wo_alpha1s, da.da152_wo_alpha1e, da.da152_wo_colcd2, da.da152_wo_alpha2s, da.da152_wo_alpha2e, da.da152_wo_colcd3, da.da152_wo_alpha3s, da.da152_wo_alpha3e, da.da152_ins_prim, da.da152_tic_xfc1, da.da152_tic_xfc2, da.da152_ins_fc, da.da152_wo_sitnum, da.da152_wo_sit_cd, da.da152_ins2dt, da.da152_multicoqual, da.da152_multicoid, da.da152_multicodir, da.da152_multicoglnum, da.da152_pat_srvcd1, da.da152_pat_srvcd2, da.da152_adchg, da.da152_adchg_var, da.da152_month_closedt, da.da152_pat_colcd, da.da152_nonaracct, da.da152_isfup_days, da.da152_arid
-> Materialize (cost=14871.84..109231.85 rows=12 width=19) (actual time=100.901..244.629 rows=448 loops=4)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
-> Hash Right Join (cost=14871.84..109231.79 rows=12 width=19) (actual time=403.596..976.869 rows=448 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Hash Cond: (((i.is1_num)::text = (vsub.visit_id)::text) AND ((i.is1_ins_full)::text = (vsub.visit_ins)::text))
Filter: (NULLIF(i.is1_bill_dt, '0001-01-01'::date) IS NULL)
Rows Removed by Filter: 2018
-> Seq Scan on public.insurance1 i (cost=0.00..90994.67 rows=336267 width=14) (actual time=0.002..283.076 rows=341075 loops=1)
Output: i.is1_num, i.is1_ins_full, i.is1_set, i.is1_prim, i.is1_stay, i.is1_direct, i.is1_admit, i.is1_disc, i.is1_from, i.is1_to, i.is1_app_sent, i.is1_app_rec, i.is1_gen_dt, i.is1_ck_dt, i.is1_contract_old, i.is1_bill_dt, i.is1_pd_dt1, i.is1_pd_amt1, i.is1_pd_dt2, i.is1_pd_amt2, i.is1_pd_dt3, i.is1_pd_amt3, i.is1_pd_status, i.is1_med_ness, i.is1_bl_furn, i.is1_bl_rep, i.is1_bl_n_rep, i.is1_bl_rate, i.is1_bl_chg, i.is1_bl_non, i.is1_coamt, i.is1_expay, i.is1_semi_rate, i.is1_diem, i.is1_cd, i.is1_typrm, i.is1_qty, i.is1_chg, i.is1_non, i.is1_opcd, i.is1_opdate, i.is1_opdesc, i.is1_opchg, i.is1_opphy, i.is1_totchg, i.is1_totnon, i.is1_maxlines, i.is1_totlines, i.is1_apc_sw, i.is1_eapc_reim, i.is1_eapc_copay, i.is1_eapc_contr, i.is1_eapc_ded, i.is1_eapc_outlr, i.is1_aapc_reim, i.is1_aapc_copay, i.is1_aapc_contr, i.is1_aapc_ded, i.is1_aapc_outlr, i.is1_mr_okayed, i.is1_mr_ok_init, i.is1_a_ded, i.is1_dayfull, i.is1_dayco, i.is1_daylife, i.is1_bl_ded, i.is1_bl_d_amt, i.is1_contr2, i.is1_copay, i.is1_colim, i.is1_covrmrate, i.is1_lifeused, i.is1_covdays, i.is1_nondays, i.is1_co_used, i.is1_typary, i.is1_effdt, i.is1_covrate, i.is1_endcare, i.is1_drg, i.is1_p_name, i.is1_birth, i.is1_print, i.is1_mndays, i.is1_reim_amt, i.is1_elecbill, i.is1_elecdate, i.is1_ppscode, i.is1_psrocode, i.is1_typebill, i.is1_new_op_medicare, i.is1_netreim, i.is1_serv, i.is1_printcross, i.is1_crossdate, i.is1_filetype, i.is1_releaseinfo, i.is1_pdtype1, i.is1_pdtype2, i.is1_pdtype3, i.is1_coins, i.is1_otprim, i.is1_otins, i.is1_otset, i.is1_coveragesetby, i.is1_covcalctype, i.is1_covverified, i.is1_netcalc, i.is1_orig_expay, i.is1_orig_bl_d_amt, i.is1_orig_coamt, i.is1_orig_a_ded, i.is1_orig_drg, i.is1_orig_covdays, i.is1_excrep, i.is1_exccov, i.is1_genviaautocl, i.is1_autobill, i.is1_formver, i.is1_contract, i.is1_origin, i.is1_covgoverride, i.is1_covglogname, i.is1_covgcsnum, i.is1_excchgs, i.is1_arid, i.is1_drg_icd10
-> Hash (cost=14837.16..14837.16 rows=2312 width=19) (actual time=393.928..393.928 rows=2416 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Buckets: 1024 Batches: 1 Memory Usage: 123kB
-> Seq Scan on public.visit vsub (cost=0.00..14837.16 rows=2312 width=19) (actual time=0.088..391.163 rows=2416 loops=1)
Output: vsub.visit_id, vsub.visit_ins, vsub.visit_arid, vsub.visit_disch_date
Filter: ((NULLIF(vsub.visit_disch_date, '0001-01-01'::date) IS NOT NULL) AND ((vsub.visit_servicecd_key)::text !~ '^[0-9]+$|[FHJbKkN\\+]'::text) AND ("left"((vsub.visit_id)::text, 1) <> ALL ('{F,P,J}'::text[])) AND (vsub.visit_mr_fdt >= (now() - '50 days'::interval)) AND (vsub.visit_mr_fdt <= (now() + '10 days'::interval)))
Rows Removed by Filter: 201581
-> Index Scan using inscomp1_pkey on public.insurance_company_table1 inscomp1 (cost=0.00..0.33 rows=1 width=11) (actual time=0.007..0.008 rows=1 loops=441)
Output: inscomp1.inscomp1_comp, inscomp1.inscomp1_name, inscomp1.inscomp1_addr1, inscomp1.inscomp1_addr2, inscomp1.inscomp1_city, inscomp1.inscomp1_state, inscomp1.inscomp1_zip, inscomp1.inscomp1_form, inscomp1.inscomp1_jour, inscomp1.inscomp1_prov, inscomp1.inscomp1_typebill, inscomp1.inscomp1_perdiem, inscomp1.inscomp1_diemdt, inscomp1.inscomp1_priordiem, inscomp1.inscomp1_pcused, inscomp1.inscomp1_phybillsw, inscomp1.inscomp1_approval, inscomp1.inscomp1_psro, inscomp1.inscomp1_ask_reim, inscomp1.inscomp1_reject_days, inscomp1.inscomp1_contrgl, inscomp1.inscomp1_othargl, inscomp1.inscomp1_auto_ip, inscomp1.inscomp1_auto_op, inscomp1.inscomp1_prirate, inscomp1.inscomp1_secrate, inscomp1.inscomp1_lagdays, inscomp1.inscomp1_mul1500, inscomp1.inscomp1_waitfin, inscomp1.inscomp1_opsum, inscomp1.inscomp1_write_off, inscomp1.inscomp1_transmit, inscomp1.inscomp1_detail_bl, inscomp1.inscomp1_provname, inscomp1.inscomp1_provaddr1, inscomp1.inscomp1_provaddr2, inscomp1.inscomp1_provcity, inscomp1.inscomp1_provst, inscomp1.inscomp1_provzip, inscomp1.inscomp1_cont_perc, inscomp1.inscomp1_drg_str, inscomp1.inscomp1_drg_acps, inscomp1.inscomp1_drg_dt, inscomp1.inscomp1_ub_loc2, inscomp1.inscomp1_sub_id, inscomp1.inscomp1_bcno, inscomp1.inscomp1_taxno, inscomp1.inscomp1_mcareno, inscomp1.inscomp1_mcaidno, inscomp1.inscomp1_signature, inscomp1.inscomp1_prov2, inscomp1.inscomp1_allpay, inscomp1.inscomp1_discrate, inscomp1.inscomp1_discdt, inscomp1.inscomp1_discrate2, inscomp1.inscomp1_sumitem, inscomp1.inscomp1_bank_plan, inscomp1.inscomp1_phy_1500, inscomp1.inscomp1_labmc, inscomp1.inscomp1_orer_comb, inscomp1.inscomp1_phybillex, inscomp1.inscomp1_net_reim, inscomp1.inscomp1_ask_drg, inscomp1.inscomp1_provphone, inscomp1.inscomp1_drggroup, inscomp1.inscomp1_phyins, inscomp1.inscomp1_phyub82, inscomp1.inscomp1_mnxsnf, inscomp1.inscomp1_srcpmtcde, inscomp1.inscomp1_provname2, inscomp1.inscomp1_coll_id, inscomp1.inscomp1_diagptr, inscomp1.inscomp1_tax, inscomp1.inscomp1_type_desc, inscomp1.inscomp1_revcode, inscomp1.inscomp1_arid
Index Cond: ((inscomp1.inscomp1_arid = vsub.visit_arid) AND ((inscomp1.inscomp1_comp)::text = (vsub.visit_ins)::text))
Filter: (now() >= (vsub.visit_disch_date + ((inscomp1.inscomp1_lagdays)::double precision * '1 day'::interval)))
Rows Removed by Filter: 0
Total runtime: 985.603 ms
答案 0 :(得分:1)
完全重写您的查询:
EXISTS()
短语NULLIF(a,b) IS NULL
重写为a > b
,因为b
似乎是一个N / A标记值(我建议-infinity
为此,或者只是NULL)LEFT JOIN ... NULL
更改为NOT EXISTS(...)
构造。WITH vCriteria AS (
SELECT vs.visit_id, vd.vdiag_diag
FROM visit vs
LEFT JOIN visit_diagnosis vd ON vd.vdiag_visit_key = vs.visit_id
WHERE EXISTS ( SELECT *
FROM da152 da
WHERE da.da152_arid = vs.visit_arid
AND vs.visit_disch_date <= da.da152_chgdt
)
AND EXISTS ( SELECT *
FROM insurance_company_table1 ict
WHERE ict.inscomp1_comp = vs.visit_ins
AND ict.inscomp1_arid = vs.visit_arid
AND Now() >= (vs.visit_disch_date + ict.inscomp1_lagdays * INTERVAL '1 day')
)
AND NOT EXISTS (
SELECT *
FROM insurance1 ins
WHERE ins.is1_num = vs.visit_id AND ins.is1_ins_full = vs.visit_ins
AND ins.is1_bill_dt > '0001-01-01'::date
)
AND vs.visit_mr_fdt
BETWEEN (now() - 50 * INTERVAL '1 day') AND (now() + 10 * INTERVAL '1 day')
AND vs.visit_disch_date > '0001-01-01'::date
AND vs.visit_servicecd_key ~ '^[0-9]+$|[FHJbKkN\\+]' = false
AND LEFT (vs.visit_id, 1) NOT IN ('F', 'P', 'J')
)
SELECT vCriteria.* FROM vCriteria
;
答案 1 :(得分:0)
这不会回答为什么,但我希望它有助于提供一些见解。我发现了一个列表:
select a from t1 where x in (select y from t2)
当列表中的基数较低时,就可以了,但随着列表大小的增加,效率会降低。相比之下,sem-join:
select a
from t1
where exists (
select null
from t2.x = t2.y
where t1.
)
对于大或小的列表,几乎总是有效的。
出于懒惰,我已经在我的第一次黑客中使用了列表并几乎一直后悔。当我切换到半连接时,世界应该是应有的。
那么,您是否可以尝试将查询更改为此内容并查看会发生什么?
select t.id_field, t2.field1 from table t
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
WHERE exists (
select 1
from table tt
join . . .
join . . .
where
t.id_field = tt.id_field and
<10 rows of filtering criteria>
)
要明确的是,半连接和连接之间的区别在于,如果列表中包含重复,则半连接会忽略后续出现。它不仅不会使行结果倍增,而且会为每场比赛“停止查看”。
但至于你的主要问题 - 你可以把它降到原来的三秒钟吗?我对此表示怀疑,因为我怀疑内部查询是额外的九秒来自哪里。
- 编辑 -
这可能比你愿意处理的代码更多,以节省9秒,但是当你运行它时会发生什么?
CREATE OR REPLACE FUNCTION test()
RETURNS TABLE (
id_field varchar,
field1 varchar
) AS
$BODY$
DECLARE
id_field_list varchar[];
BEGIN
SELECT array_agg (t.id_field)
into id_field_list
from table t
JOIN . . .
JOIN . . .
WHERE <10 rows of filtering criteria>;
return query
select t.id_field, t2.field1 from table t
LEFT JOIN table2 t2 ON t2.t_id_field = t.id_field
WHERE t.id_field = any(id_field_list);
END
$BODY$
LANGUAGE plpgsql;
当然,您可以从以下网址获取查询结果:
select * from test();