最近在适配个MySQL应用的项目,各种SQL改成PG兼容的语法真的是脑壳痛,今天遇到个有意思的案例。

原 MySQL SQL语句:

SELECT
DISTINCT
l.MALL_NAME '项目',
t.CONT_NO '合同编号',
t.COMPANY_NAME '租户',
t.STORE_NOS '铺位号',
(select GROUP_CONCAT(r.FLOOR_NAME SEPARATOR ',') from bfbfbf r where r.id in (
select s.FLOOR_ID from bsssb s where s.id in (
select substring_index(substring_index(t1.store_ids, ',', b.help_topic_id + 1), ',', -1) a from bc t1
left join mysql.help_topic b on b.help_topic_id < (length(t1.store_ids) - length(replace(t1.store_ids, ',', '')) + 1)
where t1.CONT_NO = t.CONT_NO)
)) '楼层',
t.BRAND_NAME '品牌',
l1.DICT_NAME '一级业态',
l2.DICT_NAME '二级业态',
l3.DICT_NAME '三级业态',
t.LAYOUT_NAME '签约业态',
t.SHARE_SQUARE '套内面积',
t.RENT_SQUARE '计租面积',
t.STRUCTURE_SQUARE '建筑面积',
t.CONT_BEGIN_DATE A,
IFNULL( CONT_FAIL_DATE, CONT_END_DATE ) B,
CASE
t.`STATUS`
WHEN '0' THEN
'未签约'
WHEN '1' THEN
'已审核'
WHEN '2' THEN
'已解约'
WHEN '3' THEN
'待审核'
WHEN '5' THEN
'已结算' ELSE '未知类型'
END '状态',
(SELECT RENT_TYPE FROM bccdq e where e.CONT_NO = t.CONT_NO and e.IS_DEL = '0' and e.RENT_TYPE is not null order by e.CREATED_DATE desc limit 1) '计租方式',
(select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202301' and m1.CONT_NO = t.CONT_NO limit 1) '2023年1月销售额',
(select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202301' and m1.CONT_NO = t.CONT_NO limit 1) '2023年1月销售笔数',
(select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202302' and m1.CONT_NO = t.CONT_NO limit 1) '2023年2月销售额',
(select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202302' and m1.CONT_NO = t.CONT_NO limit 1) '2023年2月销售笔数',
(select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202303' and m1.CONT_NO = t.CONT_NO limit 1) '2023年3月销售额',
(select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202303' and m1.CONT_NO = t.CONT_NO limit 1) '2023年3月销售笔数',
(select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202304' and m1.CONT_NO = t.CONT_NO limit 1) '2023年4月销售额',
(select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202304' and m1.CONT_NO = t.CONT_NO limit 1) '2023年4月销售笔数',
(select CONFIRM_AMOUNT from msamsuo m1 where SALE_YM = '202305' and m1.CONT_NO = t.CONT_NO limit 1) '2023年5月销售额',
(select CONFIRM_COUNT from msamsuo m1 where SALE_YM = '202305' and m1.CONT_NO = t.CONT_NO limit 1) '2023年5月销售笔数',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-01' and IS_DEL = '0' limit 1) '2023年1月固定租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-02' and IS_DEL = '0' limit 1) '2023年2月固定租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-03' and IS_DEL = '0' limit 1) '2023年3月固定租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-04' and IS_DEL = '0' limit 1) '2023年4月固定租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '01' and FINANCE_PERIOD = '2023-05' and IS_DEL = '0' limit 1) '2023年5月固定租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-01' and IS_DEL = '0' limit 1) '2023年1月提成租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-02' and IS_DEL = '0' limit 1) '2023年2月提成租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-03' and IS_DEL = '0' limit 1) '2023年3月提成租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-04' and IS_DEL = '0' limit 1) '2023年4月提成租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '1010' and FINANCE_PERIOD = '2023-05' and IS_DEL = '0' limit 1) '2023年5月提成租金',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-01' and IS_DEL = '0' limit 1) '2023年1月物业管理费',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-02' and IS_DEL = '0' limit 1) '2023年2月物业管理费',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-03' and IS_DEL = '0' limit 1) '2023年3月物业管理费',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-04' and IS_DEL = '0' limit 1) '2023年4月物业管理费',
(select RECE_AMOUNT from FIRCVWZZZZ e where e.cont_no = t.cont_no and e.FEE_TYPE = '02' and FINANCE_PERIOD = '2022-05' and IS_DEL = '0' limit 1) '2023年5月物业管理费' FROM
bc t
LEFT JOIN bms l ON l.id = t.MALL_ID
LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 4 ) l4 ON l4.ID = t.LAYOUT
LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 3 ) l3 ON ( l3.ID = t.LAYOUT OR l4.PARENT_ID = l3.ID )
LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 2 ) l2 ON ( l2.ID = t.LAYOUT OR l3.PARENT_ID = l2.ID )
LEFT JOIN ( SELECT * FROM bsggldddict WHERE `LEVEL` = 1 ) l1 ON l2.PARENT_ID = l1.ID
WHERE
l.MALL_TYPE = '1'
and t.IS_DEL = '0'
AND t.STATUS IN ( 1, 2, 5 )
AND t.CONT_BEGIN_DATE <= '2023-05-31' AND IFNULL( CONT_FAIL_DATE, CONT_END_DATE ) >= '2023-01-01';

这条SQL是首先改成postgresql 兼容的语法,其实要改的内容不多,只有一个标量子查询处需要改写:

    (select GROUP_CONCAT(r.FLOOR_NAME SEPARATOR ',') from bfbfbf r where r.id in (
select s.FLOOR_ID from bsssb s where s.id in (
select substring_index(substring_index(t1.store_ids, ',', b.help_topic_id + 1), ',', -1) a from bc t1
left join mysql.help_topic b on b.help_topic_id < (length(t1.store_ids) - length(replace(t1.store_ids, ',', '')) + 1)
where t1.CONT_NO = t.CONT_NO)
)) '楼层',

这里开发很聪明,使用了个小技巧使用 help_topic_id 递增的 help_topic_id 字段 + GROUP_CONCAT 函数进行行转列。

postgresql 由于没有 mysql.help_topic 表、GROUP_CONCAT、substring_index 这类函数所以需要等价改写上面的逻辑。

洽洽是这条SQL花了我几个小时来进行逻辑的等价改写,脑壳疼得厉害,还费烟,不过尝试了N次,查了不少函数终于给我改写出来了 

MySQL 逻辑等价改写 PG

(SELECT STRING_AGG(r.FLOOR_NAME, ',')
FROM bfbfbf r
WHERE r.id = ANY (ARRAY(
SELECT CAST(SUBSTRING(REGEXP_SPLIT_TO_TABLE(t1.store_ids, ','), '\d+') AS INTEGER)
FROM bc t1
WHERE t1.CONT_NO = t.CONT_NO))) AS "楼层",

等研发验证了逻辑等价以后,新的问题又来了,MySQL上这条语句跑15S就能出结果,然后到了PG需要跑 2分多种,擦,看来PG优化器性能也不咋地 ☹

不过只要是慢的问题都好解决,先看看新的SQL执行计划:

SELECT DISTINCT l.MALL_NAME            "项目",
t.CONT_NO "合同编号",
t.COMPANY_NAME "租户",
t.STORE_NOS "铺位号",
(SELECT STRING_AGG(r.FLOOR_NAME, ',')
FROM bfbfbf r
WHERE r.id = ANY (ARRAY(
SELECT CAST(SUBSTRING(REGEXP_SPLIT_TO_TABLE(t1.store_ids, ','), '\d+') AS INTEGER)
FROM bc t1
WHERE t1.CONT_NO = t.CONT_NO))) AS "楼层",
t.BRAND_NAME "品牌",
l1.DICT_NAME "一级业态",
l2.DICT_NAME "二级业态",
l3.DICT_NAME "三级业态",
t.LAYOUT_NAME "签约业态",
t.SHARE_SQUARE "套内面积",
t.RENT_SQUARE "计租面积",
t.STRUCTURE_SQUARE "建筑面积",
t.CONT_BEGIN_DATE A,
IFNULL(CONT_FAIL_DATE, CONT_END_DATE) B,
CASE t."STATUS"
WHEN '0' THEN '未签约'
WHEN '1' THEN '已审核'
WHEN '2' THEN '已解约'
WHEN '3' THEN '待审核'
WHEN '5' THEN '已结算'
ELSE '未知类型'
END "状态",
(SELECT RENT_TYPE FROM bccdq e WHERE e.CONT_NO = t.CONT_NO AND e.IS_DEL = '0' AND e.RENT_TYPE IS NOT NULL ORDER BY e.CREATED_DATE DESC LIMIT 1) AS "计租方式",
(SELECT CONFIRM_AMOUNT FROM msamsuo m1 WHERE SALE_YM = '202301' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年1月销售额",
(SELECT CONFIRM_COUNT FROM msamsuo m1 WHERE SALE_YM = '202301' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年1月销售笔数",
(SELECT CONFIRM_AMOUNT FROM msamsuo m1 WHERE SALE_YM = '202302' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年2月销售额",
(SELECT CONFIRM_COUNT FROM msamsuo m1 WHERE SALE_YM = '202302' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年2月销售笔数",
(SELECT CONFIRM_AMOUNT FROM msamsuo m1 WHERE SALE_YM = '202303' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年3月销售额",
(SELECT CONFIRM_COUNT FROM msamsuo m1 WHERE SALE_YM = '202303' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年3月销售笔数",
(SELECT CONFIRM_AMOUNT FROM msamsuo m1 WHERE SALE_YM = '202304' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年4月销售额",
(SELECT CONFIRM_COUNT FROM msamsuo m1 WHERE SALE_YM = '202304' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年4月销售笔数",
(SELECT CONFIRM_AMOUNT FROM msamsuo m1 WHERE SALE_YM = '202305' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年5月销售额",
(SELECT CONFIRM_COUNT FROM msamsuo m1 WHERE SALE_YM = '202305' AND m1.CONT_NO = t.CONT_NO LIMIT 1) AS "2023年5月销售笔数",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '01' AND FINANCE_PERIOD = '2023-01' AND IS_DEL = '0' LIMIT 1) AS "2023年1月固定租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '01' AND FINANCE_PERIOD = '2023-02' AND IS_DEL = '0' LIMIT 1) AS "2023年2月固定租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '01' AND FINANCE_PERIOD = '2023-03' AND IS_DEL = '0' LIMIT 1) AS "2023年3月固定租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '01' AND FINANCE_PERIOD = '2023-04' AND IS_DEL = '0' LIMIT 1) AS "2023年4月固定租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '01' AND FINANCE_PERIOD = '2023-05' AND IS_DEL = '0' LIMIT 1) AS "2023年5月固定租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '1010' AND FINANCE_PERIOD = '2023-01' AND IS_DEL = '0' LIMIT 1) AS "2023年1月提成租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '1010' AND FINANCE_PERIOD = '2023-02' AND IS_DEL = '0' LIMIT 1) AS "2023年2月提成租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '1010' AND FINANCE_PERIOD = '2023-03' AND IS_DEL = '0' LIMIT 1) AS "2023年3月提成租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '1010' AND FINANCE_PERIOD = '2023-04' AND IS_DEL = '0' LIMIT 1) AS "2023年4月提成租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '1010' AND FINANCE_PERIOD = '2023-05' AND IS_DEL = '0' LIMIT 1) AS "2023年5月提成租金",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '02' AND FINANCE_PERIOD = '2022-01' AND IS_DEL = '0' LIMIT 1) AS "2023年1月物业管理费",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '02' AND FINANCE_PERIOD = '2022-02' AND IS_DEL = '0' LIMIT 1) AS "2023年2月物业管理费",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '02' AND FINANCE_PERIOD = '2022-03' AND IS_DEL = '0' LIMIT 1) AS "2023年3月物业管理费",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '02' AND FINANCE_PERIOD = '2022-04' AND IS_DEL = '0' LIMIT 1) AS "2023年4月物业管理费",
(SELECT RECE_AMOUNT FROM FIRCVWZZZZ e WHERE e.cont_no = t.cont_no AND e.FEE_TYPE = '02' AND FINANCE_PERIOD = '2022-05' AND IS_DEL = '0' LIMIT 1) AS "2023年5月物业管理费"
FROM bc t
LEFT JOIN bms l ON l.id = t.MALL_ID
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 4) l4 ON l4.ID = t.LAYOUT
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 3) l3 ON (l3.ID = t.LAYOUT OR l4.PARENT_ID = l3.ID)
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 2) l2 ON (l2.ID = t.LAYOUT OR l3.PARENT_ID = l2.ID)
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 1) l1 ON l2.PARENT_ID = l1.ID
WHERE l.MALL_TYPE = '1'
AND t.IS_DEL = '0'
AND t.STATUS IN (1, 2, 5)
AND t.CONT_BEGIN_DATE <= '2023-05-31'
AND IFNULL(CONT_FAIL_DATE, CONT_END_DATE) >= '2023-01-01'; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------- -> Nested Loop Left Join (cost=15.14..1347.57 rows=21 width=188) (actual time=0.205..56.361 rows=1912 loops=1)
Join Filter: ((bsggldddict_2.ID = t.LAYOUT) OR (bsggldddict_1.PARENT_ID = bsggldddict_2.ID))
Rows Removed by Join Filter: 28686
-> Nested Loop Left Join (cost=15.14..1338.31 rows=21 width=183) (actual time=0.193..47.921 rows=1912 loops=1)
Join Filter: ((bsggldddict_1.ID = t.LAYOUT) OR (bsggldddict.PARENT_ID = bsggldddict_1.ID))
Rows Removed by Join Filter: 103267
-> Nested Loop Left Join (cost=15.14..1314.62 rows=21 width=170) (actual time=0.153..29.852 rows=1912 loops=1)
-> Hash Join (cost=15.00..1306.59 rows=21 width=162) (actual time=0.141..18.726 rows=1912 loops=1)
Hash Cond: (t.MALL_ID = l.ID)
-> Seq Scan on bc t (cost=0.00..1291.40 rows=73 width=144) (actual time=0.015..15.626 rows=4357 loops=1)
Filter: (((CONT_BEGIN_DATE)::timestamp without time zone <= '2023-05-31 00:00:00'::timestamp without time zone) AND (IFNULL((CONT_FAIL_DATE)::timestamp without time zone, (CONT_END_DATE)::timestamp without time zone) >= '2023-01-01 00:00
:00'::timestamp without time zone) AND (IS_DEL = '0'::bpchar) AND (((STATUS)::integer = 1) OR ((STATUS)::integer = 2) OR ((STATUS)::integer = 5)))
Rows Removed by Filter: 11563
-> Hash (cost=14.10..14.10 rows=72 width=34) (actual time=0.116..0.116 rows=72 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 13kB
-> Seq Scan on bms l (cost=0.00..14.10 rows=72 width=34) (actual time=0.006..0.099 rows=72 loops=1)
Filter: ((MALL_TYPE)::text = '1'::text)
Rows Removed by Filter: 176
-> Index Scan using IDX_ID_49C39C7E on bsggldddict (cost=0.14..0.38 rows=1 width=16) (actual time=0.004..0.004 rows=0 loops=1912)
Index Cond: (ID = t.LAYOUT)
Filter: ("LEVEL" = 4)
Rows Removed by Filter: 1
-> Materialize (cost=0.00..3.61 rows=55 width=29) (actual time=0.000..0.003 rows=55 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_1 (cost=0.00..3.34 rows=55 width=29) (actual time=0.005..0.021 rows=55 loops=1)
Filter: ("LEVEL" = 3)
Rows Removed by Filter: 52
-> Materialize (cost=0.00..3.42 rows=16 width=29) (actual time=0.000..0.001 rows=16 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_2 (cost=0.00..3.34 rows=16 width=29) (actual time=0.004..0.026 rows=16 loops=1)
Filter: ("LEVEL" = 2)
Rows Removed by Filter: 91
-> Materialize (cost=0.00..3.37 rows=6 width=21) (actual time=0.000..0.000 rows=4 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_3 (cost=0.00..3.34 rows=6 width=21) (actual time=0.003..0.018 rows=6 loops=1)
Filter: ("LEVEL" = 1)
Rows Removed by Filter: 101
SubPlan 2
-> Aggregate (cost=61.82..61.83 rows=1 width=32) (actual time=0.031..0.031 rows=1 loops=1912)
InitPlan 1 (returns $1)
-> Result (cost=0.29..30.81 rows=1000 width=4) (actual time=0.021..0.023 rows=1 loops=1912)
-> ProjectSet (cost=0.29..13.31 rows=1000 width=32) (actual time=0.017..0.018 rows=1 loops=1912)
-> Index Scan using idx_bc_1_2_3_4 on bc t1 (cost=0.29..8.30 rows=1 width=12) (actual time=0.012..0.012 rows=1 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Index Scan using IDX_ID_9460CCF1 on bfbfbf r (cost=0.28..30.98 rows=10 width=3) (actual time=0.003..0.003 rows=0 loops=1912)
Index Cond: (ID = ANY (ARRAY[$1]))
SubPlan 3
-> Limit (cost=31.45..31.45 rows=1 width=11) (actual time=0.041..0.041 rows=1 loops=1912)
-> Sort (cost=31.45..31.46 rows=5 width=11) (actual time=0.040..0.040 rows=1 loops=1912)
Sort Key: e.CREATED_DATE DESC
Sort Method: top-N heapsort Memory: 25kB
-> Bitmap Heap Scan on bccdq e (cost=4.47..31.42 rows=5 width=11) (actual time=0.021..0.032 rows=9 loops=1912)
Recheck Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
Filter: ((RENT_TYPE IS NOT NULL) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 6
Heap Blocks: exact=3014
-> Bitmap Index Scan on idx_cont_feetype_FED3F7C9 (cost=0.00..4.47 rows=7 width=0) (actual time=0.016..0.016 rows=15 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
SubPlan 4
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.020..0.020 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1 (cost=0.42..8.44 rows=1 width=7) (actual time=0.019..0.019 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202301'::text))
SubPlan 5
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_1 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202301'::text))
SubPlan 6
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_2 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202302'::text))
SubPlan 7
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_3 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202302'::text))
SubPlan 8
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_4 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202303'::text))
SubPlan 9
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_5 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202303'::text))
SubPlan 10
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_6 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202304'::text))
SubPlan 11
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_7 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202304'::text))
SubPlan 12
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_8 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202305'::text))
SubPlan 13
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using CONT_NO_82815276 on msamsuo m1_9 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202305'::text))
SubPlan 14
-> Limit (cost=273.59..277.61 rows=1 width=6) (actual time=4.769..4.770 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_1 (cost=273.59..277.61 rows=1 width=6) (actual time=4.766..4.766 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-01'::text))
Filter: (((FEE_TYPE)::text = '01'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3634
-> BitmapAnd (cost=273.59..273.59 rows=1 width=0) (actual time=4.757..4.757 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.047..0.047 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..267.77 rows=14313 width=0) (actual time=4.705..4.705 rows=14832 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-01'::text)
SubPlan 15
-> Limit (cost=300.49..304.51 rows=1 width=6) (actual time=4.720..4.720 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_2 (cost=300.49..304.51 rows=1 width=6) (actual time=4.716..4.716 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-02'::text))
Filter: (((FEE_TYPE)::text = '01'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3624
-> BitmapAnd (cost=300.49..300.49 rows=1 width=0) (actual time=4.709..4.709 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..294.67 rows=15766 width=0) (actual time=4.661..4.661 rows=14629 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-02'::text)
SubPlan 16
-> Limit (cost=292.46..296.48 rows=1 width=6) (actual time=4.906..4.906 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_3 (cost=292.46..296.48 rows=1 width=6) (actual time=4.902..4.902 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-03'::text))
Filter: (((FEE_TYPE)::text = '01'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3597
-> BitmapAnd (cost=292.46..292.46 rows=1 width=0) (actual time=4.896..4.896 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..286.64 rows=15228 width=0) (actual time=4.847..4.847 rows=14426 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-03'::text)
SubPlan 17
-> Limit (cost=258.73..262.75 rows=1 width=6) (actual time=3.797..3.797 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_4 (cost=258.73..262.75 rows=1 width=6) (actual time=3.793..3.793 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-04'::text))
Filter: (((FEE_TYPE)::text = '01'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3545
-> BitmapAnd (cost=258.73..258.73 rows=1 width=0) (actual time=3.787..3.787 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..252.91 rows=13398 width=0) (actual time=3.737..3.737 rows=13934 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-04'::text)
SubPlan 18
-> Limit (cost=232.64..236.66 rows=1 width=6) (actual time=3.619..3.619 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_5 (cost=232.64..236.66 rows=1 width=6) (actual time=3.616..3.616 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-05'::text))
Filter: (((FEE_TYPE)::text = '01'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3487
-> BitmapAnd (cost=232.64..232.64 rows=1 width=0) (actual time=3.610..3.610 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..226.82 rows=12053 width=0) (actual time=3.561..3.561 rows=13474 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-05'::text)
SubPlan 19
-> Limit (cost=273.59..277.61 rows=1 width=6) (actual time=4.760..4.760 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_6 (cost=273.59..277.61 rows=1 width=6) (actual time=4.756..4.756 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-01'::text))
Filter: (((FEE_TYPE)::text = '1010'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 3
Heap Blocks: exact=6314
-> BitmapAnd (cost=273.59..273.59 rows=1 width=0) (actual time=4.747..4.747 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..267.77 rows=14313 width=0) (actual time=4.698..4.698 rows=14832 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-01'::text)
SubPlan 20
-> Limit (cost=300.49..304.51 rows=1 width=6) (actual time=4.713..4.714 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_7 (cost=300.49..304.51 rows=1 width=6) (actual time=4.710..4.710 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-02'::text))
Filter: (((FEE_TYPE)::text = '1010'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 3
Heap Blocks: exact=6294
-> BitmapAnd (cost=300.49..300.49 rows=1 width=0) (actual time=4.701..4.701 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..294.67 rows=15766 width=0) (actual time=4.653..4.653 rows=14629 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-02'::text)
SubPlan 21
-> Limit (cost=292.46..296.48 rows=1 width=6) (actual time=4.897..4.897 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_8 (cost=292.46..296.48 rows=1 width=6) (actual time=4.893..4.893 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-03'::text))
Filter: (((FEE_TYPE)::text = '1010'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 3
Heap Blocks: exact=6238
-> BitmapAnd (cost=292.46..292.46 rows=1 width=0) (actual time=4.885..4.885 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..286.64 rows=15228 width=0) (actual time=4.837..4.837 rows=14426 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-03'::text)
SubPlan 22
-> Limit (cost=258.73..262.75 rows=1 width=6) (actual time=3.798..3.798 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_9 (cost=258.73..262.75 rows=1 width=6) (actual time=3.794..3.794 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-04'::text))
Filter: (((FEE_TYPE)::text = '1010'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 3
Heap Blocks: exact=6132
-> BitmapAnd (cost=258.73..258.73 rows=1 width=0) (actual time=3.786..3.786 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..252.91 rows=13398 width=0) (actual time=3.737..3.737 rows=13934 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-04'::text)
SubPlan 23
-> Limit (cost=232.64..236.66 rows=1 width=6) (actual time=3.600..3.601 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_10 (cost=232.64..236.66 rows=1 width=6) (actual time=3.597..3.597 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2023-05'::text))
Filter: (((FEE_TYPE)::text = '1010'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 3
Heap Blocks: exact=6023
-> BitmapAnd (cost=232.64..232.64 rows=1 width=0) (actual time=3.589..3.589 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..226.82 rows=12053 width=0) (actual time=3.540..3.540 rows=13474 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2023-05'::text)
SubPlan 24
-> Limit (cost=461.46..469.47 rows=1 width=6) (actual time=6.365..6.365 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_11 (cost=461.46..469.47 rows=1 width=6) (actual time=6.362..6.362 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2022-01'::text))
Filter: (((FEE_TYPE)::text = '02'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 1
Heap Blocks: exact=3961
-> BitmapAnd (cost=461.46..461.46 rows=2 width=0) (actual time=6.354..6.354 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..455.64 rows=24429 width=0) (actual time=6.305..6.305 rows=24827 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2022-01'::text)
SubPlan 25
-> Limit (cost=460.66..468.67 rows=1 width=6) (actual time=6.314..6.314 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_12 (cost=460.66..468.67 rows=1 width=6) (actual time=6.310..6.310 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2022-02'::text))
Filter: (((FEE_TYPE)::text = '02'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 2
Heap Blocks: exact=4007
-> BitmapAnd (cost=460.66..460.66 rows=2 width=0) (actual time=6.303..6.303 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..454.84 rows=24322 width=0) (actual time=6.254..6.254 rows=23605 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2022-02'::text)
SubPlan 26
-> Limit (cost=507.63..519.63 rows=1 width=6) (actual time=6.402..6.403 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_13 (cost=507.63..519.63 rows=1 width=6) (actual time=6.399..6.399 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2022-03'::text))
Filter: (((FEE_TYPE)::text = '02'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 2
Heap Blocks: exact=4268
-> BitmapAnd (cost=507.63..507.63 rows=3 width=0) (actual time=6.391..6.391 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.044..0.044 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..501.81 rows=26851 width=0) (actual time=6.343..6.343 rows=24746 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2022-03'::text)
SubPlan 27
-> Limit (cost=420.51..428.52 rows=1 width=6) (actual time=6.222..6.222 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_14 (cost=420.51..428.52 rows=1 width=6) (actual time=6.218..6.218 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2022-04'::text))
Filter: (((FEE_TYPE)::text = '02'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 2
Heap Blocks: exact=4375
-> BitmapAnd (cost=420.51..420.51 rows=2 width=0) (actual time=6.211..6.211 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..414.69 rows=22169 width=0) (actual time=6.162..6.162 rows=24456 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2022-04'::text)
SubPlan 28
-> Limit (cost=360.30..368.31 rows=1 width=6) (actual time=5.649..5.649 rows=1 loops=1912)
-> Bitmap Heap Scan on FIRCVWZZZZ e_15 (cost=360.30..368.31 rows=1 width=6) (actual time=5.645..5.645 rows=1 loops=1912)
Recheck Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FINANCE_PERIOD)::text = '2022-05'::text))
Filter: (((FEE_TYPE)::text = '02'::text) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 2
Heap Blocks: exact=4402
-> BitmapAnd (cost=360.30..360.30 rows=2 width=0) (actual time=5.638..5.638 rows=0 loops=1912)
-> Bitmap Index Scan on INX_CONT_NO_668B3A17 (cost=0.00..5.57 rows=152 width=0) (actual time=0.045..0.045 rows=222 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Bitmap Index Scan on INX_FINANCE_PERIOD_C53DF1AB (cost=0.00..354.49 rows=18941 width=0) (actual time=5.589..5.589 rows=19628 loops=1912)
Index Cond: ((FINANCE_PERIOD)::text = '2022-05'::text)
Planning Time: 6.431 ms
Execution Time: 143065.735 ms
(283 行记录)

可以看到,基本都是标量子查询产生filter过多导致整体缓慢,最主要的是标量子查询大部分还是 Bitmap Heap Scan ,而不是 Index Scan。

加两条索引再跑一下试试

create index  idx_fa_1_2_3_4  on FIRCVWZZZZ (CONT_NO, FEE_TYPE, FINANCE_PERIOD, IS_DEL);
create index idx_msam_contno_saleym on msamsuo (CONT_NO, SALE_YM);
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Unique (cost=7747.95..7750.21 rows=21 width=758) (actual time=935.263..937.220 rows=1912 loops=1)
-> Sort (cost=7747.95..7748.01 rows=21 width=758) (actual time=935.262..935.390 rows=1912 loops=1)
Sort Key: l.MALL_NAME, t.CONT_NO, t.COMPANY_NAME, t.STORE_NOS, ((SubPlan 2)), t.BRAND_NAME, bsggldddict_3.DICT_NAME, bsggldddict_2.DICT_NAME, bsggldddict_1.DICT_NAME, t.LAYOUT_NAME, t.SHARE_SQUARE, t.RENT_SQUARE, t.STRUCTURE_SQUARE, t.CONT_BEGIN_DATE, (IFNULL((t.C
ONT_FAIL_DATE)::timestamp without time zone, (t.CONT_END_DATE)::timestamp without time zone)), (CASE t.STATUS WHEN '0'::bpchar THEN '未签约'::text WHEN '1'::bpchar THEN '已审核'::text WHEN '2'::bpchar THEN '已解约'::text WHEN '3'::bpchar THEN '待审核'::text WHEN '5'::bpchar THEN '
结算'::text ELSE '未知类型'::text END), ((SubPlan 3)), ((SubPlan 4)), ((SubPlan 5)), ((SubPlan 6)), ((SubPlan 7)), ((SubPlan 8)), ((SubPlan 9)), ((SubPlan 10)), ((SubPlan 11)), ((SubPlan 12)), ((SubPlan 13)), ((SubPlan 14)), ((SubPlan 15)), ((SubPlan 16)), ((SubPlan 17)), ((SubPlan
18)), ((SubPlan 19)), ((SubPlan 20)), ((SubPlan 21)), ((SubPlan 22)), ((SubPlan 23)), ((SubPlan 24)), ((SubPlan 25)), ((SubPlan 26)), ((SubPlan 27)), ((SubPlan 28))
Sort Method: quicksort Memory: 861kB
-> Nested Loop Left Join (cost=15.14..7747.49 rows=21 width=758) (actual time=0.830..911.658 rows=1912 loops=1)
Join Filter: (bsggldddict_2.PARENT_ID = bsggldddict_3.ID)
Rows Removed by Join Filter: 5678
-> Nested Loop Left Join (cost=15.14..1347.57 rows=21 width=188) (actual time=0.198..43.046 rows=1912 loops=1)
Join Filter: ((bsggldddict_2.ID = t.LAYOUT) OR (bsggldddict_1.PARENT_ID = bsggldddict_2.ID))
Rows Removed by Join Filter: 28686
-> Nested Loop Left Join (cost=15.14..1338.31 rows=21 width=183) (actual time=0.186..36.326 rows=1912 loops=1)
Join Filter: ((bsggldddict_1.ID = t.LAYOUT) OR (bsggldddict.PARENT_ID = bsggldddict_1.ID))
Rows Removed by Join Filter: 103267
-> Nested Loop Left Join (cost=15.14..1314.62 rows=21 width=170) (actual time=0.150..19.731 rows=1912 loops=1)
-> Hash Join (cost=15.00..1306.59 rows=21 width=162) (actual time=0.136..13.738 rows=1912 loops=1)
Hash Cond: (t.MALL_ID = l.ID)
-> Seq Scan on bc t (cost=0.00..1291.40 rows=73 width=144) (actual time=0.016..11.766 rows=4357 loops=1)
Filter: (((CONT_BEGIN_DATE)::timestamp without time zone <= '2023-05-31 00:00:00'::timestamp without time zone) AND (IFNULL((CONT_FAIL_DATE)::timestamp without time zone, (CONT_END_DATE)::timestamp without time zone) >= '2023-01-01 00:00
:00'::timestamp without time zone) AND (IS_DEL = '0'::bpchar) AND (((STATUS)::integer = 1) OR ((STATUS)::integer = 2) OR ((STATUS)::integer = 5)))
Rows Removed by Filter: 11563
-> Hash (cost=14.10..14.10 rows=72 width=34) (actual time=0.111..0.112 rows=72 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 13kB
-> Seq Scan on bms l (cost=0.00..14.10 rows=72 width=34) (actual time=0.006..0.094 rows=72 loops=1)
Filter: ((MALL_TYPE)::text = '1'::text)
Rows Removed by Filter: 176
-> Index Scan using IDX_ID_49C39C7E on bsggldddict (cost=0.14..0.38 rows=1 width=16) (actual time=0.002..0.002 rows=0 loops=1912)
Index Cond: (ID = t.LAYOUT)
Filter: ("LEVEL" = 4)
Rows Removed by Filter: 1
-> Materialize (cost=0.00..3.61 rows=55 width=29) (actual time=0.000..0.003 rows=55 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_1 (cost=0.00..3.34 rows=55 width=29) (actual time=0.006..0.020 rows=55 loops=1)
Filter: ("LEVEL" = 3)
Rows Removed by Filter: 52
-> Materialize (cost=0.00..3.42 rows=16 width=29) (actual time=0.000..0.001 rows=16 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_2 (cost=0.00..3.34 rows=16 width=29) (actual time=0.004..0.018 rows=16 loops=1)
Filter: ("LEVEL" = 2)
Rows Removed by Filter: 91
-> Materialize (cost=0.00..3.37 rows=6 width=21) (actual time=0.000..0.000 rows=4 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_3 (cost=0.00..3.34 rows=6 width=21) (actual time=0.003..0.016 rows=6 loops=1)
Filter: ("LEVEL" = 1)
Rows Removed by Filter: 101
SubPlan 2
-> Aggregate (cost=61.82..61.83 rows=1 width=32) (actual time=0.022..0.022 rows=1 loops=1912)
InitPlan 1 (returns $1)
-> Result (cost=0.29..30.81 rows=1000 width=4) (actual time=0.015..0.017 rows=1 loops=1912)
-> ProjectSet (cost=0.29..13.31 rows=1000 width=32) (actual time=0.013..0.014 rows=1 loops=1912)
-> Index Scan using idx_bc_1_2_3_4 on bc t1 (cost=0.29..8.30 rows=1 width=12) (actual time=0.010..0.010 rows=1 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Index Scan using IDX_ID_9460CCF1 on bfbfbf r (cost=0.28..30.98 rows=10 width=3) (actual time=0.002..0.002 rows=0 loops=1912)
Index Cond: (ID = ANY (ARRAY[$1]))
SubPlan 3
-> Limit (cost=31.45..31.45 rows=1 width=11) (actual time=0.035..0.035 rows=1 loops=1912)
-> Sort (cost=31.45..31.46 rows=5 width=11) (actual time=0.034..0.034 rows=1 loops=1912)
Sort Key: e.CREATED_DATE DESC
Sort Method: top-N heapsort Memory: 25kB
-> Bitmap Heap Scan on bccdq e (cost=4.47..31.42 rows=5 width=11) (actual time=0.018..0.028 rows=9 loops=1912)
Recheck Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
Filter: ((RENT_TYPE IS NOT NULL) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 6
Heap Blocks: exact=3014
-> Bitmap Index Scan on idx_cont_feetype_FED3F7C9 (cost=0.00..4.47 rows=7 width=0) (actual time=0.015..0.015 rows=15 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
SubPlan 4
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.017..0.017 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1 (cost=0.42..8.44 rows=1 width=7) (actual time=0.016..0.016 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202301'::text))
SubPlan 5
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_1 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202301'::text))
SubPlan 6
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_2 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202302'::text))
SubPlan 7
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_3 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202302'::text))
SubPlan 8
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_4 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202303'::text))
SubPlan 9
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_5 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202303'::text))
SubPlan 10
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_6 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202304'::text))
SubPlan 11
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_7 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202304'::text))
SubPlan 12
-> Limit (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_8 (cost=0.42..8.44 rows=1 width=7) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202305'::text))
SubPlan 13
-> Limit (cost=0.42..8.44 rows=1 width=4) (actual time=0.014..0.014 rows=1 loops=1912)
-> Index Scan using idx_msam_contno_saleym on msamsuo m1_9 (cost=0.42..8.44 rows=1 width=4) (actual time=0.013..0.013 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((SALE_YM)::text = '202305'::text))
SubPlan 14
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.019..0.019 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_1 (cost=0.43..8.45 rows=1 width=6) (actual time=0.018..0.018 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '01'::text) AND ((FINANCE_PERIOD)::text = '2023-01'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 15
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_2 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '01'::text) AND ((FINANCE_PERIOD)::text = '2023-02'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 16
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_3 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '01'::text) AND ((FINANCE_PERIOD)::text = '2023-03'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 17
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_4 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '01'::text) AND ((FINANCE_PERIOD)::text = '2023-04'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 18
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_5 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '01'::text) AND ((FINANCE_PERIOD)::text = '2023-05'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 19
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.017..0.017 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_6 (cost=0.43..8.45 rows=1 width=6) (actual time=0.017..0.017 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '1010'::text) AND ((FINANCE_PERIOD)::text = '2023-01'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 20
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_7 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '1010'::text) AND ((FINANCE_PERIOD)::text = '2023-02'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 21
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_8 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '1010'::text) AND ((FINANCE_PERIOD)::text = '2023-03'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 22
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_9 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '1010'::text) AND ((FINANCE_PERIOD)::text = '2023-04'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 23
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_10 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '1010'::text) AND ((FINANCE_PERIOD)::text = '2023-05'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 24
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_11 (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '02'::text) AND ((FINANCE_PERIOD)::text = '2022-01'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 25
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_12 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '02'::text) AND ((FINANCE_PERIOD)::text = '2022-02'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 26
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_13 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '02'::text) AND ((FINANCE_PERIOD)::text = '2022-03'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 27
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_14 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '02'::text) AND ((FINANCE_PERIOD)::text = '2022-04'::text) AND ((IS_DEL)::text = '0'::text))
SubPlan 28
-> Limit (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
-> Index Scan using idx_fa_1_2_3_4 on FIRCVWZZZZ e_15 (cost=0.43..8.45 rows=1 width=6) (actual time=0.015..0.015 rows=1 loops=1912)
Index Cond: (((CONT_NO)::text = (t.CONT_NO)::text) AND ((FEE_TYPE)::text = '02'::text) AND ((FINANCE_PERIOD)::text = '2022-05'::text) AND ((IS_DEL)::text = '0'::text))
Planning Time: 6.469 ms
Execution Time: 937.735 ms
(163 行记录)

可以看到在标量子查询处,刚才创建的索引都用上了,SQL执行时间从2分钟降到 937ms 就能执行完成,Index Scan才 是正确的执行计划 

最后再附带标量子查询等价改写 left join 一个版本,这个就属于自己玩了,没提供给研发 ,仅供学习使用

WITH m1 AS (
SELECT cont_no,
MAX(CASE WHEN sale_ym = '202301' THEN confirm_amount END) AS "2023年1月销售额",
MAX(CASE WHEN sale_ym = '202301' THEN confirm_count END) AS "2023年1月销售笔数",
MAX(CASE WHEN sale_ym = '202302' THEN confirm_amount END) AS "2023年2月销售额",
MAX(CASE WHEN sale_ym = '202302' THEN confirm_count END) AS "2023年2月销售笔数",
MAX(CASE WHEN sale_ym = '202303' THEN confirm_amount END) AS "2023年3月销售额",
MAX(CASE WHEN sale_ym = '202303' THEN confirm_count END) AS "2023年3月销售笔数",
MAX(CASE WHEN sale_ym = '202304' THEN confirm_amount END) AS "2023年4月销售额",
MAX(CASE WHEN sale_ym = '202304' THEN confirm_count END) AS "2023年4月销售笔数",
MAX(CASE WHEN sale_ym = '202305' THEN confirm_amount END) AS "2023年5月销售额",
MAX(CASE WHEN sale_ym = '202305' THEN confirm_count END) AS "2023年5月销售笔数"
FROM msamsuo
WHERE sale_ym BETWEEN '202301' AND '202305'
GROUP BY cont_no
),fr AS (
SELECT cont_no,
MAX(CASE WHEN finance_period = '2023-01' AND fee_type = '01' THEN rece_amount END) AS "2023年1月固定租金",
MAX(CASE WHEN finance_period = '2023-02' AND fee_type = '01' THEN rece_amount END) AS "2023年2月固定租金",
MAX(CASE WHEN finance_period = '2023-03' AND fee_type = '01' THEN rece_amount END) AS "2023年3月固定租金",
MAX(CASE WHEN finance_period = '2023-04' AND fee_type = '01' THEN rece_amount END) AS "2023年4月固定租金",
MAX(CASE WHEN finance_period = '2023-05' AND fee_type = '01' THEN rece_amount END) AS "2023年5月固定租金",
MAX(CASE WHEN finance_period = '2023-01' AND fee_type = '1010' THEN rece_amount END) AS "2023年1月提成租金",
MAX(CASE WHEN finance_period = '2023-02' AND fee_type = '1010' THEN rece_amount END) AS "2023年2月提成租金",
MAX(CASE WHEN finance_period = '2023-03' AND fee_type = '1010' THEN rece_amount END) AS "2023年3月提成租金",
MAX(CASE WHEN finance_period = '2023-04' AND fee_type = '1010' THEN rece_amount END) AS "2023年4月提成租金",
MAX(CASE WHEN finance_period = '2023-05' AND fee_type = '1010' THEN rece_amount END) AS "2023年5月提成租金",
MAX(CASE WHEN finance_period = '2023-01' AND fee_type = '02' THEN rece_amount END) AS "2023年1月物业管理费",
MAX(CASE WHEN finance_period = '2023-02' AND fee_type = '02' THEN rece_amount END) AS "2023年2月物业管理费",
MAX(CASE WHEN finance_period = '2023-03' AND fee_type = '02' THEN rece_amount END) AS "2023年3月物业管理费",
MAX(CASE WHEN finance_period = '2023-04' AND fee_type = '02' THEN rece_amount END) AS "2023年4月物业管理费",
MAX(CASE WHEN finance_period = '2023-05' AND fee_type = '02' THEN rece_amount END) AS "2023年5月物业管理费"
FROM FIRCVWZZZZ
WHERE finance_period BETWEEN '2023-01' AND '2023-05'
AND is_del = '0'
GROUP BY cont_no
)
SELECT DISTINCT l.MALL_NAME "项目",
t.CONT_NO "合同编号",
t.COMPANY_NAME "租户",
t.STORE_NOS "铺位号",
(SELECT STRING_AGG(r.FLOOR_NAME, ',')
FROM bfbfbf r
WHERE r.id = ANY (ARRAY(
SELECT CAST(SUBSTRING(REGEXP_SPLIT_TO_TABLE(t1.store_ids, ','), '\d+') AS INTEGER)
FROM bc t1
WHERE t1.CONT_NO = t.CONT_NO))) AS "楼层",
t.BRAND_NAME "品牌",
l1.DICT_NAME "一级业态",
l2.DICT_NAME "二级业态",
l3.DICT_NAME "三级业态",
t.LAYOUT_NAME "签约业态",
t.SHARE_SQUARE "套内面积",
t.RENT_SQUARE "计租面积",
t.STRUCTURE_SQUARE "建筑面积",
t.CONT_BEGIN_DATE A,
IFNULL(CONT_FAIL_DATE, CONT_END_DATE) B,
CASE t."STATUS"
WHEN '0' THEN '未签约'
WHEN '1' THEN '已审核'
WHEN '2' THEN '已解约'
WHEN '3' THEN '待审核'
WHEN '5' THEN '已结算'
ELSE '未知类型'
END "状态",
(SELECT RENT_TYPE
FROM bccdq e
WHERE e.CONT_NO = t.CONT_NO
AND e.IS_DEL = '0'
AND e.RENT_TYPE IS NOT NULL
ORDER BY e.CREATED_DATE DESC
LIMIT 1) AS "计租方式",
m1."2023年1月销售额" ,
m1."2023年1月销售笔数" ,
m1."2023年2月销售额" ,
m1."2023年2月销售笔数" ,
m1."2023年3月销售额" ,
m1."2023年3月销售笔数" ,
m1."2023年4月销售额" ,
m1."2023年4月销售笔数" ,
m1."2023年5月销售额" ,
m1."2023年5月销售笔数" ,
fr."2023年1月固定租金" ,
fr."2023年2月固定租金" ,
fr."2023年3月固定租金" ,
fr."2023年4月固定租金" ,
fr."2023年5月固定租金" ,
fr."2023年1月提成租金" ,
fr."2023年2月提成租金" ,
fr."2023年3月提成租金" ,
fr."2023年4月提成租金" ,
fr."2023年5月提成租金" ,
fr."2023年1月物业管理费" ,
fr."2023年2月物业管理费" ,
fr."2023年3月物业管理费" ,
fr."2023年4月物业管理费" ,
fr."2023年5月物业管理费"
FROM bc t
LEFT JOIN bms l ON l.id = t.MALL_ID
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 4) l4 ON l4.ID = t.LAYOUT
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 3) l3 ON (l3.ID = t.LAYOUT OR l4.PARENT_ID = l3.ID)
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 2) l2 ON (l2.ID = t.LAYOUT OR l3.PARENT_ID = l2.ID)
LEFT JOIN (SELECT * FROM bsggldddict WHERE "LEVEL" = 1) l1 ON l2.PARENT_ID = l1.ID
LEFT JOIN m1 ON (m1.CONT_NO = t.CONT_NO)
LEFT JOIN fr ON (fr.cont_no = t.cont_no)
/* LEFT JOIN (SELECT cont_no,
rent_type,
ROW_NUMBER() OVER (PARTITION BY cont_no ORDER BY created_date DESC) AS rn
FROM bccdq WHERE is_del = '0' AND rent_type IS NOT NULL) e ON (e.CONT_NO = t.CONT_NO) */
WHERE l.MALL_TYPE = '1'
AND t.IS_DEL = '0'
AND t.STATUS IN (1, 2, 5)
AND t.CONT_BEGIN_DATE <= '2023-05-31'
AND IFNULL(CONT_FAIL_DATE, CONT_END_DATE) >= '2023-01-01';
    QUERY PLAN

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
Unique (cost=96438.36..96440.62 rows=21 width=1058) (actual time=484.161..486.031 rows=1912 loops=1)
-> Sort (cost=96438.36..96438.41 rows=21 width=1058) (actual time=484.160..484.290 rows=1912 loops=1)
Sort Key: l.MALL_NAME, t.CONT_NO, t.COMPANY_NAME, t.STORE_NOS, ((SubPlan 2)), t.BRAND_NAME, bsggldddict_3.DICT_NAME, bsggldddict_2.DICT_NAME, bsggldddict_1.DICT_NAME, t.LAYOUT_NAME, t.SHARE_SQUARE, t.RENT_SQUARE, t.STRUCTURE_SQUARE, t.CONT_BEGIN_DATE, (IFNULL((t.C
ONT_FAIL_DATE)::timestamp without time zone, (t.CONT_END_DATE)::timestamp without time zone)), (CASE t.STATUS WHEN '0'::bpchar THEN '未签约'::text WHEN '1'::bpchar THEN '已审核'::text WHEN '2'::bpchar THEN '已解约'::text WHEN '3'::bpchar THEN '待审核'::text WHEN '5'::bpchar THEN '
结算'::text ELSE '未知类型'::text END), ((SubPlan 3)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202301'::text) THEN msamsuo.CONFIRM_AMOUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202301'::text) THEN mng_sale_a
mount_month.CONFIRM_COUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202302'::text) THEN msamsuo.CONFIRM_AMOUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202302'::text) THEN mng_sale_amou
nt_month.CONFIRM_COUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202303'::text) THEN msamsuo.CONFIRM_AMOUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202303'::text) THEN mng_sale_amount_
month.CONFIRM_COUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202304'::text) THEN msamsuo.CONFIRM_AMOUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202304'::text) THEN mng_sale_amount_mon
th.CONFIRM_COUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202305'::text) THEN msamsuo.CONFIRM_AMOUNT ELSE NULL::numeric END)), (max(CASE WHEN ((msamsuo.SALE_YM)::text = '202305'::text) THEN msamsuo.
CONFIRM_COUNT ELSE NULL::numeric END)), fr."2023年1月固定租金", fr."2023年2月固定租金", fr."2023年3月固定租金", fr."2023年4月固定租金", fr."2023年5月固定租金", fr."2023年1月提成租金", fr."2023年2月提成租金", fr."2023年3月提成租金", fr."2023年4月提成租金", fr."2023年5月提成租金", fr
."2023年1月物业管理费", fr."2023年2月物业管理费", fr."2023年3月物业管理费", fr."2023年4月物业管理费", fr."2023年5月物业管理费"
Sort Method: quicksort Memory: 896kB
-> Nested Loop Left Join (cost=94174.57..96437.90 rows=21 width=1058) (actual time=324.580..459.882 rows=1912 loops=1)
Join Filter: ((bsggldddict_2.ID = t.LAYOUT) OR (bsggldddict_1.PARENT_ID = bsggldddict_2.ID))
Rows Removed by Join Filter: 28686
-> Nested Loop Left Join (cost=94171.16..94465.97 rows=21 width=983) (actual time=324.375..351.578 rows=1912 loops=1)
Join Filter: ((bsggldddict_1.ID = t.LAYOUT) OR (bsggldddict.PARENT_ID = bsggldddict_1.ID))
Rows Removed by Join Filter: 103267
-> Hash Left Join (cost=94171.16..94442.28 rows=21 width=970) (actual time=324.350..335.203 rows=1912 loops=1)
Hash Cond: (t.LAYOUT = bsggldddict.ID)
-> Hash Right Join (cost=94167.45..94438.51 rows=21 width=962) (actual time=324.303..334.204 rows=1912 loops=1)
Hash Cond: ((msamsuo.CONT_NO)::text = (t.CONT_NO)::text)
-> HashAggregate (cost=19272.76..19386.83 rows=11407 width=331) (actual time=78.407..84.658 rows=5707 loops=1)
Group Key: msamsuo.CONT_NO
-> Bitmap Heap Scan on msamsuo (cost=575.04..17866.18 rows=26792 width=29) (actual time=24.886..36.601 rows=27189 loops=1)
Recheck Cond: (((SALE_YM)::text >= '202301'::text) AND ((SALE_YM)::text <= '202305'::text))
Heap Blocks: exact=5919
-> Bitmap Index Scan on INX_SALE_YM_3DCD12EF (cost=0.00..568.34 rows=26792 width=0) (actual time=24.068..24.069 rows=27189 loops=1)
Index Cond: (((SALE_YM)::text >= '202301'::text) AND ((SALE_YM)::text <= '202305'::text))
-> Hash (cost=74894.42..74894.42 rows=21 width=642) (actual time=245.872..245.876 rows=1912 loops=1)
Buckets: 2048 (originally 1024) Batches: 1 (originally 1) Memory Usage: 508kB
-> Hash Left Join (cost=73602.77..74894.42 rows=21 width=642) (actual time=232.789..243.568 rows=1912 loops=1)
Hash Cond: ((t.CONT_NO)::text = (fr.cont_no)::text)
-> Hash Join (cost=15.00..1306.59 rows=21 width=162) (actual time=0.131..9.620 rows=1912 loops=1)
Hash Cond: (t.MALL_ID = l.ID)
-> Seq Scan on bc t (cost=0.00..1291.40 rows=73 width=144) (actual time=0.014..8.737 rows=4357 loops=1)
Filter: (((CONT_BEGIN_DATE)::timestamp without time zone <= '2023-05-31 00:00:00'::timestamp without time zone) AND (IFNULL((CONT_FAIL_DATE)::timestamp without time zone, (CONT_END_DATE)::timestamp without time zone) >= '2023
-01-01 00:00:00'::timestamp without time zone) AND (IS_DEL = '0'::bpchar) AND (((STATUS)::integer = 1) OR ((STATUS)::integer = 2) OR ((STATUS)::integer = 5)))
Rows Removed by Filter: 11563
-> Hash (cost=14.10..14.10 rows=72 width=34) (actual time=0.109..0.110 rows=72 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 13kB
-> Seq Scan on bms l (cost=0.00..14.10 rows=72 width=34) (actual time=0.005..0.092 rows=72 loops=1)
Filter: ((MALL_TYPE)::text = '1'::text)
Rows Removed by Filter: 176
-> Hash (cost=73455.92..73455.92 rows=10548 width=491) (actual time=232.634..232.636 rows=4893 loops=1)
Buckets: 16384 Batches: 1 Memory Usage: 678kB
-> Subquery Scan on fr (cost=73244.96..73455.92 rows=10548 width=491) (actual time=221.100..230.052 rows=4893 loops=1)
-> HashAggregate (cost=73244.96..73350.44 rows=10548 width=491) (actual time=221.099..229.259 rows=4893 loops=1)
Group Key: FIRCVWZZZZ.CONT_NO
-> Bitmap Heap Scan on FIRCVWZZZZ (cost=2683.78..67477.83 rows=50149 width=27) (actual time=69.354..92.470 rows=51955 loops=1)
Recheck Cond: (((FINANCE_PERIOD)::text >= '2023-01'::text) AND ((FINANCE_PERIOD)::text <= '2023-05'::text) AND ((IS_DEL)::text = '0'::text))
Heap Blocks: exact=12083
-> Bitmap Index Scan on INX_FINANCE_PERIOD_RECE_NO_989A97EA (cost=0.00..2671.24 rows=50149 width=0) (actual time=67.535..67.535 rows=51955 loops=1)
Index Cond: (((FINANCE_PERIOD)::text >= '2023-01'::text) AND ((FINANCE_PERIOD)::text <= '2023-05'::text) AND ((IS_DEL)::text = '0'::text))
-> Hash (cost=3.34..3.34 rows=30 width=16) (actual time=0.034..0.034 rows=30 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 10kB
-> Seq Scan on bsggldddict (cost=0.00..3.34 rows=30 width=16) (actual time=0.022..0.028 rows=30 loops=1)
Filter: ("LEVEL" = 4)
Rows Removed by Filter: 77
-> Materialize (cost=0.00..3.61 rows=55 width=29) (actual time=0.000..0.003 rows=55 loops=1912)
-> Seq Scan on bsggldddict bsggldddict_1 (cost=0.00..3.34 rows=55 width=29) (actual time=0.006..0.020 rows=55 loops=1)
Filter: ("LEVEL" = 3)
Rows Removed by Filter: 52
-> Materialize (cost=3.41..6.87 rows=16 width=34) (actual time=0.000..0.001 rows=16 loops=1912)
-> Hash Left Join (cost=3.41..6.79 rows=16 width=34) (actual time=0.039..0.055 rows=16 loops=1)
Hash Cond: (bsggldddict_2.PARENT_ID = bsggldddict_3.ID)
-> Seq Scan on bsggldddict bsggldddict_2 (cost=0.00..3.34 rows=16 width=29) (actual time=0.004..0.015 rows=16 loops=1)
Filter: ("LEVEL" = 2)
Rows Removed by Filter: 91
-> Hash (cost=3.34..3.34 rows=6 width=21) (actual time=0.020..0.020 rows=6 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Seq Scan on bsggldddict bsggldddict_3 (cost=0.00..3.34 rows=6 width=21) (actual time=0.004..0.014 rows=6 loops=1)
Filter: ("LEVEL" = 1)
Rows Removed by Filter: 101
SubPlan 2
-> Aggregate (cost=61.82..61.83 rows=1 width=32) (actual time=0.019..0.019 rows=1 loops=1912)
InitPlan 1 (returns $1)
-> Result (cost=0.29..30.81 rows=1000 width=4) (actual time=0.014..0.015 rows=1 loops=1912)
-> ProjectSet (cost=0.29..13.31 rows=1000 width=32) (actual time=0.012..0.013 rows=1 loops=1912)
-> Index Scan using idx_bc_1_2_3_4 on bc t1 (cost=0.29..8.30 rows=1 width=12) (actual time=0.010..0.010 rows=1 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
-> Index Scan using IDX_ID_9460CCF1 on bfbfbf r (cost=0.28..30.98 rows=10 width=3) (actual time=0.002..0.002 rows=0 loops=1912)
Index Cond: (ID = ANY (ARRAY[$1]))
SubPlan 3
-> Limit (cost=31.45..31.45 rows=1 width=11) (actual time=0.032..0.032 rows=1 loops=1912)
-> Sort (cost=31.45..31.46 rows=5 width=11) (actual time=0.032..0.032 rows=1 loops=1912)
Sort Key: e.CREATED_DATE DESC
Sort Method: top-N heapsort Memory: 25kB
-> Bitmap Heap Scan on bccdq e (cost=4.47..31.42 rows=5 width=11) (actual time=0.018..0.027 rows=9 loops=1912)
Recheck Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
Filter: ((RENT_TYPE IS NOT NULL) AND ((IS_DEL)::text = '0'::text))
Rows Removed by Filter: 6
Heap Blocks: exact=3014
-> Bitmap Index Scan on idx_cont_feetype_FED3F7C9 (cost=0.00..4.47 rows=7 width=0) (actual time=0.014..0.014 rows=15 loops=1912)
Index Cond: ((CONT_NO)::text = (t.CONT_NO)::text)
Planning Time: 4.134 ms
Execution Time: 486.659 ms
(88 行记录)

最后可以看到 486 ms 就能出结果,比刚才加索引优化也快了一半。

总结:作为PG的开发,对SQL的熟练度要求还是要蛮高的。

mysql 代码适配 postgresql 适配改写,优化案例(行转列 + 标量子查询改写)的更多相关文章

  1. 优化有标量子查询的SQL

    数据库环境:SQL SERVER 2008R2 今天在数据库中抓出一条比较耗费资源的SQL,只返回904条数据,居然跑了40多分钟.SQL及对应的数据量如下图: SELECT saft04.cur_y ...

  2. Oracle sql优化之分析函数优化标量子查询

    待优化语句如下 select a.code as code, a.m_code as m_code,a.stktype as f_stype,a.e_year as e_year, b.sname a ...

  3. 标量子查询SQL改写

    一网友说下面sql跑的好慢,让我看看 sql代码: select er, cid, pid, tbl, zs, sy, (select count(sr.mobile_tele_no) from tb ...

  4. 标量子查询加聚合函数sql改写一

    标量子查询的语句: select /*+ GATHER_PLAN_STATISTICS dwtest */ empno, (select count(*) from DEPT1 b where b.i ...

  5. SQL Server的优化器会缓存标量子查询结果集吗

    在这篇博客"ORACLE当中自定义函数性优化浅析"中,我们介绍了通过标量子查询缓存来优化函数性能: 标量子查询缓存(scalar subquery caching)会通过缓存结果减 ...

  6. MySQL 使用profile分析慢sql,group left join效率高于子查询

    MySQL 使用profile分析慢sql,group left join效率高于子查询 http://blog.csdn.net/mchdba/article/details/54380221 -- ...

  7. 在MySQL中使用子查询和标量子查询的基本用法

    一.MySQL 子查询 子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用.MySQL 支持 SQL 标准要求的所有子查询格式和操作,也扩展了特有的几种特性.子查询没 ...

  8. 优化系列 | DELETE子查询改写优化

    0.导读 有个采用子查询的DELETE执行得非常慢,改写成SELECT后执行却很快,最后把这个子查询DELETE改写成JOIN优化过程 1.问题描述 朋友遇到一个怪事,一个用子查询的DELETE,执行 ...

  9. mysql update/delete in 子查询改写

    #子查询(不支持) limit ,); #改写 limit ,) t ; #子查询(不支持) delete from `user` where id in ( ) ); #改写 delete from ...

  10. SQL中带有NOT IN 子查询改写

    报表程序中的一段SQL运行很慢,代码如下: 优化前: 耗时:1337s INSERT INTO PER_LTE_ZIB_PB_COMMISSION_07 SELECT P.TOPACTUALID, Q ...

随机推荐

  1. Oracle分组取最大值

    需求 该SQL是一个子SQL,需要查询出某个人所有过往履历中职务最高的 SELECT a."EMP_ID",a."CADRE_LEVEL" FROM (SELE ...

  2. 基于 Spark 的物流企业数据仓库 的设计与实现

    1.设计和实现了一种基于 Spark 的分布式 ETL 系统,包括利用 Spark 抽取.转换清洗和加载数据的具体过程. 2.设计和实现了基于 Spark 的物流企业数据仓库,包括物流企业数据仓库的分 ...

  3. 利用Python爬取免费代理IP

    # 2019/9/8 # 思路: 1.找到一个免费的ip代理网站(如:西刺代理) # # 2.爬取ip(常规爬取requests+BeautifulSoup) # # 3.验证ip有效性(携带爬取到的 ...

  4. 使用 FastGPT 构建高质量 AI 知识库

    作者:余金隆.FastGPT 项目作者,Sealos 项目前端负责人,前 Shopee 前端开发工程师 FastGPT 项目地址:https://github.com/labring/FastGPT/ ...

  5. G-channel 实现低光图像增强

    G-channel 之前研究低光图像增强时,看到一篇博客,里面介绍了一种方法,没有说明出处,也没有说明方法的名字,这里暂时叫做 G-channel 算法. 博客地址:低照度图像增强(附步骤及源码)_低 ...

  6. 关于预处理器 sass 的超全用法

    随着用户需求的增加,应用于页面的 css 代码越来越复杂越发臃肿难以维护,但是又没有 css 的替代品,css 预处理器作为 css 的扩展,出现在前端技术中. sass 是 css 预处理器中常用的 ...

  7. 在langchain中使用自定义example selector

    简介 在之前的文章中,我们提到了可以在跟大模型交互的时候,给大模型提供一些具体的例子内容,方便大模型从这些内容中获取想要的答案.这种方便的机制在langchain中叫做FewShotPromptTem ...

  8. 从零玩转系列之微信支付实战PC端项目构建+页面基础搭建 | 技术创作特训营第一期

    一.前言 欢迎来到本期的博客!在这篇文章中,我们将带您深入了解前端开发领域中的一个热门话题: 如何使用 Vue 3 和 Vite 构建前端项目.随着现代 Web 应用程序的需求不断演进, 选择适当的工 ...

  9. 独奏者2 序章的wp

    0x01 0ctf_2017_babyheap 2023.7.24 国防科技大学 合肥 本题除了fastbin attack,最重要的是伪造fakechunk,使得存放chunk的指针有两个指向同一个 ...

  10. 文心一言 VS 讯飞星火 VS chatgpt (76)-- 算法导论7.3 1题

    一.如果用go语言,为什么我们分析随机化算法的期望运行时间,而不是其最坏运行时间呢? 文心一言: 在分析算法的性能时,期望运行时间是一个重要的指标,它描述了算法在平均情况下的表现.期望运行时间考虑了所 ...