|
接楼主的问题,最近一直想类似的问题,
需求是很简单每个月1号的时候通过java的定时任务把这个累计值归零.
desc T_RISK_BANK_SUM
BANK_SUM_ID NUMBER(12)
DAY_SUM NUMBER(17,2)
MONTH_SUM NUMBER(17,2)
当前的SQL是这样:
update t_risk_bank_sum set day_sum=0,month_sum=0 where day_sum >0 or month_sum>0;
查了下上个月的记录数据的分布是这样的.
SQL> select cnt, cnt_day_sum/cnt, cnt_month_sum/cnt from (select count(*) cnt ,sum(decode(day_sum,0,0,1)) cnt_day_sum,sum(decode(month_sum,0,0,1)) cnt_month_sum from t_risk_bank_sum a );
CNT CNT_DAY_SUM/CNT CNT_MONTH_SUM/CNT
---------- --------------- -----------------
19999880 .049746348 .04993345
现在的索引是复合索引:
OWNER TABNAME INDNAME UNIQ STATUS COLNAME
--------------- ------------------------- ---------------------------------------- --------- -------- -------------------------
BPEP_RISK T_RISK_BANK_SUM IDX_T_RISK_BANK_DAY_MONTH NONUNIQUE VALID DAY_SUM
BPEP_RISK T_RISK_BANK_SUM IDX_T_RISK_BANK_DAY_MONTH NONUNIQUE VALID MONTH_SUM
一直在想怎么优化这个SQL或者改写SQL.
or条件的时候,只能走FTS
SQL> explain plan for update bpep_risk.t_risk_bank_sum set day_sum=0,month_sum=0 where day_sum >0 or month_sum>0;
Explained.
SQL> @plan
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1136648923
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 903K| 4409K| 87215 (6)| 00:07:36 |
| 1 | UPDATE | T_RISK_BANK_SUM | | | | |
|* 2 | TABLE ACCESS FULL| T_RISK_BANK_SUM | 903K| 4409K| 87215 (6)| 00:07:36 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------
2 - filter("DAY_SUM">0 OR "MONTH_SUM">0)
14 rows selected.
请教下各位专家有啥好的方案.
我想的有如下几个
1 直接用SQL: truncate table bpep_risk.t_risk_bank_sum . 这是效率最高的SQL,但在实际环境中我们是不允许业务代码SQL中使用DDL语句的.
2 通过Oracle存储过程. -- 同样被禁用的.
3 对day_sum,month_sum分别建立单列索引 ?
|
|