index和like的问题

joinrry 2004-07-14 11:20:29
有个表,t_charge,字段如下:
Name Type Nullable Default Comments
------------- ------------ -------- ------- --------
C_SETNO NUMBER(10)
C_CALLER VARCHAR2(20)
C_ASERVICENUM VARCHAR2(20)
C_PROGRAMNO VARCHAR2(20)
C_AGENTNO CHAR(5) Y
C_BEGINTIME DATE Y
C_ENDTIME DATE Y
C_TOTALTIME NUMBER(6) Y
C_UNITTIME NUMBER(3) Y
C_RATIO NUMBER(8,2) Y
C_STATUS CHAR(1) Y

有两个索引,c_setno为主索引,c_caller为一般索引
在有c_caller索引的情况下,下列sql语句速度得到提升。
select * from t_charge where c_caller='1000000';
在PB中,有以c_caller索引的情况下,反而速度得到下降,没有的时候快很多
SELECT rpad("T_CHARGE"."C_CALLER",11),
rpad("T_CHARGE"."C_ASERVICENUM"||"T_CHARGE"."C_PROGRAMNO",11),
COUNT(1),
SUM("T_CHARGE"."C_TOTALTIME"),
SUM(CEIL("T_CHARGE"."C_TOTALTIME"/"T_CHARGE"."C_UNITTIME")*"T_CHARGE"."C_RATIO")
FROM "T_CHARGE"
WHERE "T_CHARGE"."C_STATUS" = '1' AND "T_CHARGE"."C_UNITTIME"> 0 AND "T_CHARGE"."C_TOTALTIME" >:i_timeset AND
TO_CHAR("T_CHARGE"."C_BEGINTIME",'YYYY/MM/DD') >= :AS_BEGIN_DATE AND
TO_CHAR("T_CHARGE"."C_ENDTIME",'YYYY/MM/DD') <= :AS_END_DATE AND
"T_CHARGE"."C_CALLER" like :AS_CALLER
GROUP BY rpad("T_CHARGE"."C_CALLER",11), rpad("T_CHARGE"."C_ASERVICENUM"||"T_CHARGE"."C_PROGRAMNO",11)

有问是什么原因 呢?
...全文
195 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
万年水母 2004-07-18
  • 打赏
  • 举报
回复
倒,like不能用索引,那oracle不用开公司了。
主要是这3段
TO_CHAR("T_CHARGE"."C_BEGINTIME",'YYYY/MM/DD') >= :AS_BEGIN_DATE AND
TO_CHAR("T_CHARGE"."C_ENDTIME",'YYYY/MM/DD') <= :AS_END_DATE AND
"T_CHARGE"."C_CALLER" like :AS_CALLER

如果没建函数索引,to_char已经把查询变成full table scan了。还有你的AS_CALLER变量不要用%开头,否则索引失效。想用'%ABC%'形式的话,只能full table scan了。
joinrry 2004-07-18
  • 打赏
  • 举报
回复
我知道是LIKE不能用索引啊。唉,我自己解决啦,
joinrry 2004-07-17
  • 打赏
  • 举报
回复
这个c_caller的索引一定得要,
但是在PB那个语句里面会明显降低查询速度,咋回事?
joinrry 2004-07-17
  • 打赏
  • 举报
回复
还是没有解决问题,
大家快帮帮忙
dinya2003 2004-07-15
  • 打赏
  • 举报
回复
以下情况不使用索引
select * from tablename where id+0=1
where user_name||''= 'smith'
where to_number(字段)=4
where user_name like '%D'
where user_name like 'D%'
where user_name like '%D%'
where user_name like 'D%D'
where to_char(字段)='k'
where nvl(字段,'0')='3'
where to_date(字段)
......
--以上排除建了函数索引的情况,如果想用索引则建立函数索引.

提高执行速度:
1.尽量少在条件中用to_number,to_date等的计算,
2.尽量少用复杂的表达式.
3.尽量少用where id=nvl(:id,id)
4.字段变长时用where user_name ='name',定长时用where user_name like 'name'
.....
jxc 2004-07-14
  • 打赏
  • 举报
回复
执行计划应该和前台工具没有关系,估计你的两个sql语句有不同的地方
minkoming 2004-07-14
  • 打赏
  • 举报
回复
建议你用SQL_TRACE看看到底你的SQL语句是如何写的,然后用EXPLAN看看执行计划。
或许PB给你的SQL语句添加了一些东西
joinrry 2004-07-14
  • 打赏
  • 举报
回复
不对啊,我在sql/plus命令窗口中运行这个语句速度满快啊,为什么在PB中会慢呢?
joinrry 2004-07-14
  • 打赏
  • 举报
回复
是啊,我也怀疑是不是index对于INDEX来说无效呢
LGQDUCKY 2004-07-14
  • 打赏
  • 举报
回复
你看下这条语句的执行计划
,是否使用上索引
SELECT rpad("T_CHARGE"."C_CALLER",11),
rpad("T_CHARGE"."C_ASERVICENUM"||"T_CHARGE"."C_PROGRAMNO",11),
COUNT(1),
SUM("T_CHARGE"."C_TOTALTIME"),
SUM(CEIL("T_CHARGE"."C_TOTALTIME"/"T_CHARGE"."C_UNITTIME")*"T_CHARGE"."C_RATIO")
FROM "T_CHARGE"
WHERE "T_CHARGE"."C_STATUS" = '1' AND "T_CHARGE"."C_UNITTIME"> 0 AND "T_CHARGE"."C_TOTALTIME" >:i_timeset AND
TO_CHAR("T_CHARGE"."C_BEGINTIME",'YYYY/MM/DD') >= :AS_BEGIN_DATE AND
TO_CHAR("T_CHARGE"."C_ENDTIME",'YYYY/MM/DD') <= :AS_END_DATE AND
"T_CHARGE"."C_CALLER" like :AS_CALLER
GROUP BY rpad("T_CHARGE"."C_CALLER",11), rpad("T_CHARGE"."C_ASERVICENUM"||"T_CHARGE"."C_PROGRAMNO",11)

bzszp 2004-07-14
  • 打赏
  • 举报
回复
你的like可能根本使用不上索引,如c_caller like '%aa';
看一下执行计划,
beckhambobo 2004-07-14
  • 打赏
  • 举报
回复
模糊查询根本发辉索引作用,可以考虑函数索引
joinrry 2004-07-14
  • 打赏
  • 举报
回复
郁闷,也不行啊
bzszp 2004-07-14
  • 打赏
  • 举报
回复
我用过pb8,没遇到过这种问题
你在pb8里面的数据窗口中retrieve一下看看快不快
joinrry 2004-07-14
  • 打赏
  • 举报
回复
原样拷贝过来的,肯定语句一样

17,082

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧