函数是快,因为在服务器上运行只返回结果给你,查询则在前面调用函数.当然要慢些,而且是在前端处理group by.
建议楼主将该查询放到服务器上执行,用游标,然后返回一个记录集到前端程序.直接在前端显示你要的数据就行了.
建议楼主将该查询放到服务器上执行,用游标,然后返回一个记录集到前端程序.直接在前端显示你要的数据就行了.
解决方案 »
- 关于oracle number类型的问题
- oracle 10g directory manager 启动
- 十万火急,数据库连接不上,可能是数据库崩溃吧,在线等待
- 本地计算机 无法启动OracleOraHome90Agent 服务
- 如何将女改为男?
- 关于排序问题,为何顺序不对呢
- 请教ORACLE9i启动异常
- [java调用Oracle存储过程问题]存储过程执行正确,只是java中getXXX()不能正确返回值
- 给表临时字段赋值汉子,有没有人知道这个问题!
- 这个问题怎么解决,好几天了,一直没办法解决
- 在存储过程中,能不能用sql语句往一个游标里填数据,而不是从表中查询,并返回这个游标?因为我的存储过程需要经过复杂的计算,得到结果
- decode函数的问题,大家帮帮忙
我的这个汉数很简单,就是找一条记录的几个数据项,跟据每个数据项来确定要返回的结果。to dinya2003(OK) :
请问游标执行的快马?
我在前段发出去的sql不都是在服务端执行的码?请详细些号码?我没能完全理解你的意思。谢谢啊。
我是在服务器的sqlplus里做的测试,速度很慢啊,因为需要函数计算。如果是有现成的数据sum,速度非常快。
可以直接用SQL完成的。你用函数的话,首先,它在执行你的函数的时候,就需要几乎扫描你的整个表,
这样的话,你的记录越多,他坐起来越慢。这个可是迪卡尔集。
我觉得,说出你的需求,和表结构,可以有办法解决的。
我的需求是这样的:
统计单位的每个部门的完成任务数,并按任务数排序;而每个部门的任务数是由每个部门的人员完成的任务数加起来的。
表结构: t_user_task
myid number(8) --流水号
user_id char(8) --人员id
depart_id char(4) --所属部门id
sales_num number(16,2) --完成销售额
add_date date --加办日期
undo_date date --撤办日期
biz_type char(1) --业务类型
state char(1) --状态 注释:add_date:销售完成后入库日期
undo_date: 销售退回日期
biz_type:区别业务类型 可为 1,2,3
任务数=(销售额折算)乘以(0.3)
销售额折算:是根据状态、业务类型、加办日期、撤办日期算出的一个数。
在统计任务数的时候一定会给出一个时间段。
因为销售额的折算是一个逻辑处理单元,用一个简单的sql很难实现(起码目前这么认为),所以写了个函数:f_count_task,f_count_task接收员工号、起始日期、终止日期三个参数。
但感觉运行起来效果不好,速度太慢,我的表数据量有几十万。
如果不写函数,又不知道怎么写好?
请大虾帮忙指点啊。
还有增加union的调用!
减少重复的索引!!!
建议做以下几件事:
1.把你函数的具体实现贴出来,让别人给你看看sql是不是可以改进
2.explain plan看下执行全过程
3.执行后查看下V$SQL视图
return number as
v1 char(1);
v2 char(2);
v3 number(16,2);
v4 date;
v5 date;
v6 date;
set9 number(2);
begin
execute immediate 'select state,biz_type,saving_num,add_date,withdraw_date,start_date from t_user_task where acc='||in_a into v1,v2,v3,v4,v5,v6; if v1='1' then
if(v2='20') then
return round(v3*25/10000,2);
elsif(v2='21') then
return round(v3*50/10000,2);
elsif(v2='23') then
return round(v3/100,2);
else
return round(v3/100,2);
end if;
elsif v1='2' then
if(v4>=in_b) then
if(v2='20') then
return round(v3*25/10000,2);
elsif(v2='21') then
return round(v3*50/10000,2);
elsif(v2='23') then
return round(v3/100,2);
else
return round(v3/100,2);
end if;
else
return 0;
end if;
elsif v1='3' then
if((v4>=in_b and v4<=in_c) and (v5>=in_b and v5<=in_c)) then
if((v5-v4)>=360) then
return v3/100;
else
select set9 into set9 from t_mgr_rule where area_id=in_d;
if(v2='20') then
return round(v3*(v5-v6)*set9*0.25/360000,2);
elsif(v2='21') then
return round(v3*(v5-v6)*set9*0.5/360000,2);
else
return round(v3*(v5-v6)*set9/360000,2);
end if;
end if;
elsif (in_b>v4) then
if((v5-v4)>=360) then
return 0;
else
select set9 into set9 from t_mgr_rule where area_id=in_d;
if(v2='20') then
return round(v3*(v5-v6)*set9*0.25/360000-v3/100,2);
elsif(v2='21') then
return round(v3*(v5-v6)*set9*0.5/360000-v3/100,2);
else
return round(v3*(v5-v6)*set9/360000-v3/100,2);
end if;
end if;
elsif (v5>in_c) then
if(v2='20') then
return round(v3*25/10000,2);
elsif(v2='21') then
return round(v3*50/10000,2);
elsif(v2='23') then
return round(v3/100,2);
else
return round(v3/100,2);
end if;
end if;
end if;exception
when others then
return -1;
end f_user_task;
其次:你用了group by depart_id ,就要在depart_id 字段建立索引,我想,你的速度应该会提高很多!--------希望告诉结果给我!
请问 “ to_date('20040101','yyyymmdd'),这样的函数在程序里就要转换完成”
是什么意思啊?怎么在程序转换?
建索引没问题。
有结果我会公布的。
谢谢
我不知道你用的是什么语言,但是一定是可以转换成‘to_date('20040101','yyyymmdd')’这样的格式的。也就是转换成格式date格式就可以了!
你的in_d不需要传入吗?楼上那个人的意思,是让你再传入参数的时候,不要用to_date,在你的函数里面用。
select decode(biz_type||state,'120',round(sum(saving_num)*25/10000,2)) from t_user_task;不过太复杂的逻辑操作………………
这种操作无论如何最后是要排序
在解决sql语句的效率后,应调大 sort_area的值,还有temp表空间的大小