FUND

The Shaanxi Natural Science Plan Project of China

Grant NO.: 2014JM8322

select * from ( WITH A AS ( SELECT 'ROOT' ADDVCD,'全国' ADDVNM FROM DUAL ), B AS ( select 'ROOT' ADDVCD, count(case when FUND_DATE = '2022' then 1 end) PLAN2022, count(case when FUND_DATE = '2023' then 1 end) PLAN2023, count(case when FUND_DATE = '2024' then 1 end) PLAN2024, count(case when FUND_DATE = '2025' then 1 end) PLAN2025, count(case when FUND_DATE in ('2022','2023','2024') then 1 end) PLANSUM, count(case when FUND_DATE = '2022' and IS_YR = '1' then 1 end) ZJ2022, count(case when FUND_DATE = '2023' and IS_YR = '1' then 1 end) ZJ2023, count(case when FUND_DATE = '2024' and IS_YR = '1' then 1 end) ZJ2024, count(case when FUND_DATE = '2025' and IS_YR = '1' then 1 end) ZJ2025, count(case when FUND_DATE in ('2022','2023','2024') and IS_YR = '1' then 1 end) ZJSUM, count(case when FUND_DATE in ('2022','2023','2024','2025') and IS_YR = '1' then 1 end) ZJ, sum(case when FUND_DATE = '2022' then FUND end) FUND2022, sum(case when FUND_DATE = '2023' then FUND end) FUND2023, sum(case when FUND_DATE = '2024' then FUND end) FUND2024, sum(case when FUND_DATE = '2025' then FUND end) FUND2025, sum(case when FUND_DATE in ('2022','2023','2024') then FUND end) FUNDSUM from WI_MEAS_FUND_INVENTORY where TRANS_MODE_CODE = '1' and STATUS in ('1','2') ), C AS ( select 'ROOT' ADDVCD, SUM( case when a.FUND_DATE = '2022' then MONTH_DAY_WATER_NUMBER end) MONTH_DAY_NUMBER2022, SUM( case when a.FUND_DATE = '2023' then MONTH_DAY_WATER_NUMBER end) MONTH_DAY_NUMBER2023, SUM( case when a.FUND_DATE = '2024' then MONTH_DAY_WATER_NUMBER end) MONTH_DAY_NUMBER2024, SUM( case when a.FUND_DATE = '2025' then MONTH_DAY_WATER_NUMBER end) MONTH_DAY_NUMBER2025, SUM( case when a.FUND_DATE in ('2022','2023','2024') then MONTH_DAY_WATER_NUMBER end) MONTH_DAY_NUMBERSUM, SUM( case when a.FUND_DATE = '2022' then YEAR_DAY_WATER_NUMBER end) YEAR_DAY_NUMBER2022, SUM( case when a.FUND_DATE = '2023' then YEAR_DAY_WATER_NUMBER end) YEAR_DAY_NUMBER2023, SUM( case when a.FUND_DATE = '2024' then YEAR_DAY_WATER_NUMBER end) YEAR_DAY_NUMBER2024, SUM( case when a.FUND_DATE = '2025' then YEAR_DAY_WATER_NUMBER end) YEAR_DAY_NUMBER2025, SUM( case when a.FUND_DATE in ('2022','2023','2024') then YEAR_DAY_WATER_NUMBER end) YEAR_DAY_NUMBERSUM, SUM( case when a.FUND_DATE = '2022' then case when b.id is not null then YJ_MONTH_WATER_NUMBER else to_number(to_char(sysdate -1, 'dd')) end end) YJ_MONTH_NUMBER2022, SUM( case when a.FUND_DATE = '2023' then case when b.id is not null then YJ_MONTH_WATER_NUMBER else to_number(to_char(sysdate -1, 'dd')) end end) YJ_MONTH_NUMBER2023, SUM( case when a.FUND_DATE = '2024' then case when b.id is not null then YJ_MONTH_WATER_NUMBER else to_number(to_char(sysdate -1, 'dd')) end end) YJ_MONTH_NUMBER2024, SUM( case when a.FUND_DATE = '2025' then case when b.id is not null then YJ_MONTH_WATER_NUMBER else to_number(to_char(sysdate -1, 'dd')) end end) YJ_MONTH_NUMBER2025, SUM( case when a.FUND_DATE in ('2022','2023','2024') then case when b.id is not null then YJ_MONTH_WATER_NUMBER else to_number(to_char(sysdate -1, 'dd')) end end) YJ_MONTH_NUMBERSUM, SUM( case when a.FUND_DATE = '2022' then case when b.id is not null then YJ_YEAR_WATER_NUMBER else to_number(to_char(sysdate -1, 'ddd')) -180 end end) YJ_YEAR_NUMBER2022, SUM( case when a.FUND_DATE = '2023' then case when b.id is not null then YJ_YEAR_WATER_NUMBER else to_number(to_char(sysdate -1, 'ddd')) -180 end end) YJ_YEAR_NUMBER2023, SUM( case when a.FUND_DATE = '2024' then case when b.id is not null then YJ_YEAR_WATER_NUMBER else to_number(to_char(sysdate -1, 'ddd')) -180 end end) YJ_YEAR_NUMBER2024, SUM( case when a.FUND_DATE = '2025' then case when b.id is not null then YJ_YEAR_WATER_NUMBER else to_number(to_char(sysdate -1, 'ddd')) -180 end end) YJ_YEAR_NUMBER2025, SUM( case when a.FUND_DATE in ('2022','2023','2024') then case when b.id is not null then YJ_YEAR_WATER_NUMBER else to_number(to_char(sysdate -1, 'ddd')) -180 end end) YJ_YEAR_NUMBERSUM, COUNT( case when a.FUND_DATE = '2022' and IS_WATER_ABNORMAL_MONTH = '1' then 1 end) ABNORMAL_MONTH2022, COUNT( case when a.FUND_DATE = '2023' and IS_WATER_ABNORMAL_MONTH = '1' then 1 end) ABNORMAL_MONTH2023, COUNT( case when a.FUND_DATE = '2024' and IS_WATER_ABNORMAL_MONTH = '1' then 1 end) ABNORMAL_MONTH2024, COUNT( case when a.FUND_DATE = '2025' and IS_WATER_ABNORMAL_MONTH = '1' then 1 end) ABNORMAL_MONTH2025, COUNT( case when a.FUND_DATE in ('2022','2023','2024') and IS_WATER_ABNORMAL_MONTH = '1' then 1 end) ABNORMAL_MONTHSUM, COUNT( case when a.FUND_DATE = '2022' and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEAR2022, COUNT( case when a.FUND_DATE = '2023' and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEAR2023, COUNT( case when a.FUND_DATE = '2024' and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEAR2024, COUNT( case when a.FUND_DATE = '2025' and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEAR2025, COUNT( case when a.FUND_DATE in ('2022','2023','2024') and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEARSUM, COUNT( case when a.FUND_DATE in ('2022','2023','2024','2025') and IS_WATER_ABNORMAL_YEAR = '1' then 1 end) ABNORMAL_YEAR from WI_MEAS_FUND_INVENTORY a left join WI_MEASURE_WATER_MANAGE_25_12 b on b.TRANS_MODE_CODE = '1' and a.meas_code = b.meas_code and ( ( a.CERT_NUM_CODE = b.CERT_NUM_CODE and a.LICENSE_WHITELIST = '0') or a.LICENSE_WHITELIST = '1' ) where a.TRANS_MODE_CODE = '1' and a.STATUS in ('1','2') ) SELECT A.ADDVCD, A.ADDVNM, '2025-12-01' DATE_STR, B.PLAN2022, B.PLAN2023, B.PLAN2024, B.PLAN2025, B.PLANSUM, B.ZJ2022, B.ZJ2023, B.ZJ2024, B.ZJ2025, B.ZJSUM, CASE WHEN B.PLAN2022 > 0 THEN ROUND(B.ZJ2022/B.PLAN2022,4)*100 ELSE 0 END ZJ2022AR, CASE WHEN B.PLAN2023 > 0 THEN ROUND(B.ZJ2023/B.PLAN2023,4)*100 ELSE 0 END ZJ2023AR, CASE WHEN B.PLAN2024 > 0 THEN ROUND(B.ZJ2024/B.PLAN2024,4)*100 ELSE 0 END ZJ2024AR, CASE WHEN B.PLAN2025 > 0 THEN ROUND(B.ZJ2025/B.PLAN2025,4)*100 ELSE 0 END ZJ2025AR, CASE WHEN B.PLANSUM > 0 THEN ROUND(B.ZJSUM/B.PLANSUM,4)*100 ELSE 0 END ZJSUMAR, B.FUND2022, B.FUND2023, B.FUND2024, B.FUND2025, B.FUNDSUM, CASE WHEN C.YJ_MONTH_NUMBER2022 >0 THEN ROUND(C.MONTH_DAY_NUMBER2022/C.YJ_MONTH_NUMBER2022,4) *100 ELSE 0 END ZJ2022YR, CASE WHEN C.YJ_MONTH_NUMBER2023 >0 THEN ROUND(C.MONTH_DAY_NUMBER2023/C.YJ_MONTH_NUMBER2023,4) *100 ELSE 0 END ZJ2023YR, CASE WHEN C.YJ_MONTH_NUMBER2024 >0 THEN ROUND(C.MONTH_DAY_NUMBER2024/C.YJ_MONTH_NUMBER2024,4) *100 ELSE 0 END ZJ2024YR, CASE WHEN C.YJ_MONTH_NUMBER2025 >0 THEN ROUND(C.MONTH_DAY_NUMBER2025/C.YJ_MONTH_NUMBER2025,4) *100 ELSE 0 END ZJ2025YR, CASE WHEN C.YJ_MONTH_NUMBERSUM >0 THEN ROUND(C.MONTH_DAY_NUMBERSUM/C.YJ_MONTH_NUMBERSUM,4) *100 ELSE 0 END ZJSUMYR, CASE WHEN C.YJ_YEAR_NUMBER2022 > 0 THEN ROUND(C.YEAR_DAY_NUMBER2022/C.YJ_YEAR_NUMBER2022,4) *100 ELSE 0 END ZJ2022YRY, CASE WHEN C.YJ_YEAR_NUMBER2023 > 0 THEN ROUND(C.YEAR_DAY_NUMBER2023/C.YJ_YEAR_NUMBER2023,4) *100 ELSE 0 END ZJ2023YRY, CASE WHEN C.YJ_YEAR_NUMBER2024 > 0 THEN ROUND(C.YEAR_DAY_NUMBER2024/C.YJ_YEAR_NUMBER2024,4) *100 ELSE 0 END ZJ2024YRY, CASE WHEN C.YJ_YEAR_NUMBER2025 > 0 THEN ROUND(C.YEAR_DAY_NUMBER2025/C.YJ_YEAR_NUMBER2025,4) *100 ELSE 0 END ZJ2025YRY, CASE WHEN C.YJ_YEAR_NUMBERSUM > 0 THEN ROUND(C.YEAR_DAY_NUMBERSUM/C.YJ_YEAR_NUMBERSUM,4) *100 ELSE 0 END ZJSUMYRY, CASE WHEN B.ZJ2022 > 0 THEN ROUND(C.ABNORMAL_MONTH2022/B.ZJ2022,4) *100 ELSE 0 END ZJ2022ERRM, CASE WHEN B.ZJ2023 > 0 THEN ROUND(C.ABNORMAL_MONTH2023/B.ZJ2023,4) *100 ELSE 0 END ZJ2023ERRM, CASE WHEN B.ZJ2024 > 0 THEN ROUND(C.ABNORMAL_MONTH2024/B.ZJ2024,4) *100 ELSE 0 END ZJ2024ERRM, CASE WHEN B.ZJ2025 > 0 THEN ROUND(C.ABNORMAL_MONTH2025/B.ZJ2025,4) *100 ELSE 0 END ZJ2025ERRM, CASE WHEN B.ZJSUM > 0 THEN ROUND(C.ABNORMAL_MONTHSUM/B.ZJSUM,4) *100 ELSE 0 END ZJSUMERRM, CASE WHEN B.ZJ2022 > 0 THEN ROUND(C.ABNORMAL_YEAR2022/B.ZJ2022,4) *100 ELSE 0 END ZJ2022ERRY, CASE WHEN B.ZJ2023 > 0 THEN ROUND(C.ABNORMAL_YEAR2023/B.ZJ2023,4) *100 ELSE 0 END ZJ2023ERRY, CASE WHEN B.ZJ2024 > 0 THEN ROUND(C.ABNORMAL_YEAR2024/B.ZJ2024,4) *100 ELSE 0 END ZJ2024ERRY, CASE WHEN B.ZJ2025 > 0 THEN ROUND(C.ABNORMAL_YEAR2025/B.ZJ2025,4) *100 ELSE 0 END ZJ2025ERRY, CASE WHEN B.ZJSUM > 0 THEN ROUND(C.ABNORMAL_YEARSUM/B.ZJSUM,4) *100 ELSE 0 END ZJSUMERRY, CASE WHEN B.ZJ > 0 THEN ROUND(C.ABNORMAL_YEAR/B.ZJ,4) *100 ELSE 0 END ZJERRY FROM A LEFT JOIN B ON A.ADDVCD = B.ADDVCD LEFT JOIN C ON A.ADDVCD = C.ADDVCD ) 优化该sql
12-03
<think> 我们面对的是一个复杂的SQL查询优化问题,涉及WITH子句(A、B、C)和两个表的连接(WI_MEAS_FUND_INVENTORY和WI_MEASURE_WATER_MANAGE_25_12),以及大量统计计算。优化这样的查询需要多方面的策略。 首先,我们需要分析查询的执行计划(如引用[2]所建议),找出性能瓶颈。常见的瓶颈可能包括全表扫描、连接顺序不当、缺乏有效索引等。 根据引用[5],索引是优化查询性能的关键。我们需要检查连接条件、WHERE子句中的过滤条件以及GROUP BY子句中使用的列,确保这些列上有合适的索引。例如: - 在连接列上创建索引 - 在WHERE子句的过滤列上创建索引 - 在GROUP BY和聚合函数涉及的列上创建索引 引用[1]提到了子查询优化。我们需要检查WITH子句(A、B、C)中的子查询,确保它们尽可能高效。例如: - 避免在子查询中使用SELECT *,只选择必要的列 - 确保子查询不是多余的,考虑是否可以重写为连接 - 对于标量子查询,确保其只返回单个值(避免多值错误) 引用[4]展示了使用IN子查询的优化案例。我们可以考虑: - 将IN子查询改为EXISTS子查询,特别是当子查询返回大量数据时 - 或者将子查询重写为连接 此外,引用[2]中的流程图提供了多表查询优化的步骤:确定需求→选择连接类型→编写语法→控制连接顺序→优化性能→检查结果。我们应遵循此流程。 具体优化步骤建议: 1. **分析执行计划**:使用数据库工具(如Oracle的EXPLAIN PLAN)分析查询,查看全表扫描、连接顺序、索引使用情况。 2. **索引优化**: - 在连接列(如WI_MEAS_FUND_INVENTORY和WI_MEASURE_WATER_MANAGE_25_12的连接列)上创建索引。 - 在WHERE子句的过滤列上创建索引。 - 在GROUP BY和聚合计算涉及的列上创建索引。 3. **重写子查询**: - 检查WITH子句是否可以合并或简化。 - 将子查询转换为连接,特别是当子查询较大时。 - 使用EXISTS代替IN(如果适用)。 4. **减少数据量**: - 在子查询中尽早过滤数据(使用WHERE子句)。 - 避免在子查询中选择不必要的列。 5. **统计信息更新**:确保表的统计信息是最新的(引用[5]),以便优化器选择最佳执行计划。 6. **分区表**:如果表数据量极大,考虑使用分区表来提高查询效率。 示例优化代码片段(假设连接列为water_manage_id): ```sql -- 创建索引(如果不存在) CREATE INDEX idx_inventory ON WI_MEAS_FUND_INVENTORY(water_manage_id); CREATE INDEX idx_water_manage ON WI_MEASURE_WATER_MANAGE_25_12(water_manage_id); -- 优化后的查询(部分示例) WITH A AS ( SELECT /*+ MATERIALIZE */ water_manage_id, SUM(fund) AS total_fund FROM WI_MEAS_FUND_INVENTORY WHERE ... -- 添加过滤条件减少数据量 GROUP BY water_manage_id ), B AS ( SELECT /*+ MATERIALIZE */ water_manage_id, AVG(water_level) AS avg_level FROM WI_MEASURE_WATER_MANAGE_25_12 WHERE ... -- 添加过滤条件 GROUP BY water_manage_id ), C AS ( SELECT A.water_manage_id, A.total_fund, B.avg_level FROM A JOIN B ON A.water_manage_id = B.water_manage_id -- 使用索引 ) SELECT ... -- 主查询 ``` 注意:/*+ MATERIALIZE */提示(Oracle)可以将WITH子句结果物化到临时表,避免重复计算,但需权衡空间和速度。 如果问题仍然存在,请提供具体查询语句以便进一步分析。 </think>以下是针对复杂SQL查询的优化建议,结合引用内容和最佳实践: ### 优化策略分析 1. **索引优化**(引用[5]) - 为连接列和WHERE条件列创建复合索引: ```sql -- 示例索引创建 CREATE INDEX idx_inventory ON WI_MEAS_FUND_INVENTORY(water_manage_id, fund_date); CREATE INDEX idx_water_manage ON WI_MEASURE_WATER_MANAGE_25_12(water_id, measure_type); ``` - 更新统计信息确保优化器准确性: ```sql BEGIN DBMS_STATS.GATHER_TABLE_STATS(ownname => 'YOUR_SCHEMA', tabname => 'WI_MEAS_FUND_INVENTORY'); DBMS_STATS.GATHER_TABLE_STATS(ownname => 'YOUR_SCHEMA', tabname => 'WI_MEASURE_WATER_MANAGE_25_12'); END; ``` 2. **WITH子句优化**(引用[1][4]) - 物化中间结果减少重复计算: ```sql WITH A AS ( SELECT /*+ MATERIALIZE */ water_manage_id, SUM(fund_value) AS total_fund FROM WI_MEAS_FUND_INVENTORY WHERE fund_date BETWEEN :start_date AND :end_date GROUP BY water_manage_id ), B AS ( ... ) ``` 3. **连接操作优化**(引用[1][2]) - 显式指定连接顺序和控制连接类型: ```sql SELECT /*+ LEADING(A B) USE_NL(C) */ A.water_manage_id, B.measure_value, C.calculated_metric FROM A JOIN WI_MEASURE_WATER_MANAGE_25_12 B ON A.water_manage_id = B.water_id JOIN ( SELECT ... FROM ... ) C ON ... ``` 4. **统计计算优化** - 分阶段计算避免嵌套聚合: ```sql -- 替代单层复杂聚合 WITH pre_agg AS ( SELECT region, AVG(water_level) AS avg_level, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY flow_rate) AS median_flow FROM WI_MEASURE_WATER_MANAGE_25_12 GROUP BY region ) SELECT SUM(CASE WHEN avg_level > 100 THEN 1 ELSE 0 END) AS high_level_count, ... FROM pre_agg; ``` ### 执行计划检查(引用[1][2]) ```mermaid graph LR A[分析执行计划] --> B{全表扫描?} B -->|是| C[添加索引] B -->|否| D{连接顺序?} D -->|非最优| E[使用HINT调整] D -->|最优| F{统计信息准确?} F -->|否| G[更新统计信息] F -->|是| H[完成优化] ``` ### 常见错误规避(引用[1]) | 错误类型 | 解决方案 | |---------|----------| | 子查询多值 | 使用`WHERE EXISTS`替代`IN`子句 | | 连接条件缺失 | 显式指定所有连接条件 | | 统计函数误用 | 验证聚合函数作用域 | > 优化要点总结:通过索引优化减少I/O成本,重构计算步骤降低复杂度,利用物化中间结果,并持续监控执行计划变化[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值