大家帮忙分析这个SQL,高分哦

wangledong 2006-06-26 01:35:45
SQL代码如下:数据库是ORACLE 9i
select a.*
from df_zzb_2006 a, dm_djlb b
where a.zwrq=200604 and a.jgbh='520001' and a.bmid like '0002%' and a.dflb=0
and a.djlb||a.qyrq=b.djlb||b.qyrq and b.fzbz=0 and b.djlb<>0 and b.ydxz='18'

这个SQL当不加b.ydxz='18'这个条件的时候速度非常快,当加上这个条件后,如果我要select 出a表的东西,速度也是非常快,可是只要我select a表的字段就奇慢无比。大家分析一下看看是为什么?有什么解决手段和测试方法?a表记录在17W,b表有2224记录。
...全文
309 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
龙翔飞雪 2006-06-27
  • 打赏
  • 举报
回复
这样的SQL, 最通用的解决方法:
数据库理由,SQL优化第一步: 先缩小集合,在做笛卡儿积.

就是说, 先筛选无用的行与列, 再将子集相联立... 百事不爽!
wangledong 2006-06-27
  • 打赏
  • 举报
回复
问题解决,谢谢各位,我按照sozdream() 说的,写了如下SQL
select b.ydxz, nvl(sum(a.yhgs),0)
from (select djlb||qyrq YXDJ,yhgs, zwrq from df_zzb_2006 where jgbh='520001' and bmid like '0002%' and dflb=0 ) a,
(select djlb||qyrq YXDJ,ydxz from dm_djlb where fzbz=0 and djlb<>0 and ydxz='18' ) b
where a.YXDJ=b.YXDJ and a.zwrq=200604 group by b.ydxz
我先缩小结果集在做笛卡儿,可是速度是一样的慢,后来我单独把每个子表查询了,速度都非常快,那么我想就是两个子表做笛卡儿的时候的问题,我分析是每个子表字段顺序是乱的,于是我对YXDJ进行排序,哈哈,问题解决了,速度超快,谢谢大家,如果有高手还请给讲解以下这里面的问题,还有最开始的那个我加上ydxz='18'为什么速度就慢了,按道理说不加这个条件应该更慢才对。
goldarcher2005 2006-06-26
  • 打赏
  • 举报
回复
关键看a.*,b.*所占a,b表的百分比
把a.*改成1试试看还慢吗?
wangledong 2006-06-26
  • 打赏
  • 举报
回复
我按照kingofworl(良辰美景虚度)写了,问题依旧上面是我的explain plan ,大家看看那里有问题呢?
我把and b.ydxz='18' 条件去掉后explain plan 如下
SELECT STATEMENT, GOAL = CHOOSE 75 1 48
SORT GROUP BY 75 1 48
HASH JOIN 73 1 48
INDEX FAST FULL SCAN TEST PK_DM_DJLB 2 20 320
TABLE ACCESS BY INDEX ROWID TEST DF_ZZB_2006 70 74 2368
INDEX RANGE SCAN TEST PK_DF_ZZB_2006 31 1
wangledong 2006-06-26
  • 打赏
  • 举报
回复
SELECT STATEMENT, GOAL = CHOOSE 33 1 48
SORT GROUP BY NOSORT 33 1 48
TABLE ACCESS BY INDEX ROWID TEST DF_ZZB_2006 31 1 32
NESTED LOOPS 33 1 48
INDEX FAST FULL SCAN TEST PK_DM_DJLB 2 1 16
INDEX RANGE SCAN TEST PK_DF_ZZB_2006 30 1
yqwd911 2006-06-26
  • 打赏
  • 举报
回复
在where条件里尽量不要用对栏位做运算的方式。这样表大时会很慢
(a.djlb||TO_CHAR(a.qyrq))=(b.djlb||TO_CHAR(b.qyrq))

把执行计划贴出来
kingofworl 2006-06-26
  • 打赏
  • 举报
回复
and a.djlb||a.qyrq=b.djlb||b.qyrq
不如写成 a.djlb=b.djlb and a.qyrq=b.qyrq
fjmingyang 2006-06-26
  • 打赏
  • 举报
回复
估计是索引没用上,执行了 full scan 还是先看下你这条语句的执行计划把 ,

另外,我看你的where条件写得很乱 ,看有没有办法简化下
wangledong 2006-06-26
  • 打赏
  • 举报
回复
我SQL这样写
select b.ydxz,nvl(sum(a.yhgs),0)
from df_zzb_2006 a, dm_djlb b
where a.jgbh='520001' and a.bmid like '0002%' and a.zwrq=200504 and a.dflb=0
and (a.djlb||TO_CHAR(a.qyrq))=(b.djlb||TO_CHAR(b.qyrq)) and b.fzbz=0 and b.djlb>0 and b.ydxz='18' group by b.ydxz;
在a表上加了一个索引
JGBH,BMID,ZWRQ,DFLB,DJLB||TO_CHAR(QYRQ)
在b表上也加了索引
DJLB||TO_CHAR(QYRQ),FZBZ,DJLB,YDXZ
然后执行一下,速度照旧。
没有任何变化。 同样的SQL我只要把and b.ydxz='18' 条件去掉,速度就0.XX秒,否则就是几十秒
wangledong 2006-06-26
  • 打赏
  • 举报
回复
不小心写错了,是select b表的东西速度超快,a表超慢。呵呵

3,491

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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