这条Pgsql很忙优化下:select id,(select sum((case when fee_type=2 then -amount else amount end)) from bms.fin_bank_water_bill where is_delete = 'f' and (transaction_time<t.transaction_time or (transaction_time=t.transaction_time and id<=t.id)) and belong_subject_id=151 ) as balance from bms.fin_bank_water_bill t where t.is_delete = 'f' and belong_subject_id=151
时间: 2023-03-05 13:55:38 浏览: 141
这条 Pgsql 语句的作用是从表 bms.fin_bank_water_bill 中选取属于主题 151 的记录,并根据条件计算出每一条记录对应的余额,同时返回每条记录的 id 和余额。但是,由于语句嵌套和子查询的使用,这条语句可能存在性能问题。
为了优化这条语句,可以考虑以下几个方面:
1. 尽可能减少子查询的使用。可以使用 JOIN 或者子查询优化技巧来代替子查询,减少查询次数。
2. 尽可能减少表的扫描次数。可以添加索引或者使用表分区等技术,以提高查询效率。
3. 精简查询条件,尽量避免使用复杂的逻辑运算符。可以对查询条件进行合理的拆分和组合,避免重复计算和表扫描。
针对具体的查询语句,我们可以结合实际情况进行分析和优化。
相关问题
PGSQL语句该不该出现在group by后面 case when bbm.bill_main_type=16 and bbm.app_id=4 then null else COUNT ((bbm.bill_status = 30) OR NULL) end
PGSQL语句可以出现在GROUP BY后面,但是你的这个语句有一些问题。COUNT函数应该放在CASE语句的内部而不是外部。正确的语句应该是:
```
SELECT
CASE WHEN bbm.bill_main_type = 16 AND bbm.app_id = 4 THEN null
ELSE COUNT(CASE WHEN bbm.bill_status = 30 THEN 1 ELSE null END)
END
FROM your_table_name
GROUP BY bbm.bill_main_type, bbm.app_id;
```
在这个语句中,我们使用了嵌套的CASE语句来计算满足条件的行数,然后使用COUNT函数来计算这些行的数量。GROUP BY子句指定了我们要按照哪些列进行分组。
帮我优化这个pgsql select info.pot_type_name,info.ttpw_addr as twlPortName,info.ttpw_addr_code as twlPortCode,info.tmr_material_name,info.ids --库存 ,(select sum(twl_leave_stock) from tms_whe_control where twl_material_id = any(STRING_TO_ARRAY(ids, ','))and twl_port_code=ttpw_addr_code and pot_type_name='合作港口') as twl_leave_stock from ( select port.pot_type_name,ttpw.ttpw_addr ,ttpw.ttpw_addr_code,tmrGroup.tmr_material_name, array_to_string( ARRAY( SELECT unnest(string_to_array(array_to_string(array_agg(distinct(tmr.tmr_id)),','), ',')) ), ',' ) ids from tms_transport_plan_work ttpw,tms_material_ref tmr,tms_material_ref tmrGroup,pub_ports port,tms_transport_plan plan where tmr.tmr_id=ttpw_tmr_id and tmr.parent_tmr_id=tmrGroup.tmr_id and port.pot_regcd=ttpw.ttpw_addr_code and port.pot_cnname=ttpw.ttpw_addr and plan.ttp_id=ttpw.ttpw_ttp_id and plan.ttp_waybill_status >0 AND ttpw.ttpw_plan_amount > 0 GROUP BY pot_type_name,ttpw_addr,ttpw_addr_code,tmrGroup.tmr_material_name ORDER BY ttpw_addr ) as info
这个 SQL 语句有一些可优化的地方,可以考虑以下几点:
1. 尽可能使用 JOIN 代替子查询。例如,第一个子查询中的 `pub_ports` 表可以通过 JOIN 进行连接。
2. 避免使用 `array_agg` 和 `unnest` 函数。这些函数需要进行大量的数组转换操作,非常耗费资源。如果可以,可以考虑使用其他方式将数组数据按逗号拼接。
3. 在使用 GROUP BY 时,只选择必要的列。不需要 GROUP BY 的列可以在外部查询中进行选择。
4. 对于多个表的连接,可以考虑使用合适的索引来提高查询性能。
下面是优化后的 SQL 语句:
```
SELECT
pot.pot_type_name,
ttpw.ttpw_addr AS twlPortName,
ttpw.ttpw_addr_code AS twlPortCode,
tmrGroup.tmr_material_name,
array_to_string(ids, ',') AS ids,
tms_whe.twl_leave_stock
FROM (
SELECT
ttpw_tmr_id,
array_agg(DISTINCT tmr.tmr_id) AS ids,
ttpw_addr,
ttpw_addr_code,
pot_type_name,
tmrGroup.tmr_material_name
FROM tms_transport_plan_work ttpw
JOIN tms_material_ref tmr ON tmr.tmr_id = ttpw.ttpw_tmr_id
JOIN tms_material_ref tmrGroup ON tmrGroup.tmr_id = tmr.parent_tmr_id
JOIN pub_ports pot ON pot.pot_regcd = ttpw.ttpw_addr_code AND pot.pot_cnname = ttpw.ttpw_addr
WHERE ttpw_plan_amount > 0
GROUP BY ttpw_tmr_id, ttpw_addr, ttpw_addr_code, pot_type_name, tmrGroup.tmr_material_name
) AS info
LEFT JOIN (
SELECT twl_material_id, twl_port_code, SUM(twl_leave_stock) AS twl_leave_stock
FROM tms_whe_control
WHERE pot_type_name = '合作港口'
GROUP BY twl_material_id, twl_port_code
) AS tms_whe ON tms_whe.twl_material_id = ANY(ids) AND tms_whe.twl_port_code = twlPortCode
ORDER BY twlPortName
```
这个 SQL 语句使用了 JOIN 来代替子查询,并避免了使用 `array_agg` 和 `unnest` 函数。同时,只选择必要的列进行 GROUP BY,使用合适的索引来优化查询性能。
阅读全文