急,一个sql语句为什么运行这么慢,半个小时也出不来结果,可是去掉一个表的关联,马上就出来了。

zhoujia0983 2008-11-06 10:44:14
我写的一个sql语句
SELECT sfb_zddm ,tsxx_sm,tsxx_dj,kcb_dbbz*kcb_xbbz jcs,ddml_mzddm,kcb_mzddm,kcb_dbbz,kcb_xbbz,kcb_tsbm,kcb_kcs+kcb_fhs-kcb_fss kfss,sum(sfb_zds) zds,sum(sfb_fss) zfss FROM ddml,kcb,sfb,zdpc,qxhtsbm,tsxxzd WHERE ddml_mlbh = zdpc_bh AND sfb_zddm = ddml_zddm AND tsxx_tsbm=kcb_tsbm AND sfb_jcd = '370130' AND kcb_jcd= '370130' AND ddml_sjdm = qxhtsbm_zdqh||qxhtsbm_zdxh AND kcb_tsbm = qxhtsbm_tsbm AND (kcb_kcs+kcb_fhs-kcb_fss) >0 GROUP BY sfb_zddm,tsxx_sm,kcb_kcs,kcb_fhs,kcb_fss,tsxx_dj,ddml_mzddm,kcb_mzddm,kcb_dbbz,kcb_xbbz,kcb_tsbm HAVING SUM(sfb_zds) - SUM(sfb_fss) > 0 ORDER BY zds desc,kcb_tsbm,kfss desc,sfb_zddm
其中zdpc_bh、sfb_zddm、ddml_zddm、tsxx_tsbm、kcb_tsbm、qxhtsbm_zdqh、qxhtsbm_zdxh 、qxhtsbm_tsbm 都是主键,可是查询半天出不来结果,如果把qxhtsbm这个表去掉,将ddml_sjdm = qxhtsbm_zdqh||qxhtsbm_zdxh AND kcb_tsbm = qxhtsbm_tsbm 这个关联改成ddml_sjdm = kcb_tsbm马上就出来了 ,qxhtsbm这个表就三个字段qxhtsbm_zdqh、qxhtsbm_zdxh 、qxhtsbm_tsbm 全是主键,而且这个表的数据不是很多,差不多是这几个表数据最少的,可是一加上这个关联就出不来了,以前的时候没加这个表,后来专门加了这个表是代码和编码的一个对照,以前代码和编码的对照没单独拿出来,直接可以通过ddml_sjdm = kcb_tsbm关联,现在把代码和编码的对照单独提出来了放在qxhtsbm这个表,代码和编码的对照是多对多关系,加上之后死活出不来结果。大家给想个办法,到底哪个地方出了问题。

...全文
234 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenqingyu 2008-11-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 gisinfo 的回复:]
告诉你一个ORACLE执行的规则

从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适…
[/Quote]

如果你的表都分析过,应该会走CBO,这样,from和where后面的顺序无所谓.
主要的优化还是建索引,还慢的话再看看执行计划.
BlueskyWide 2008-11-06
  • 打赏
  • 举报
回复

SELECT sfb_zddm,
tsxx_sm,
tsxx_dj,
kcb_dbbz * kcb_xbbz jcs,
ddml_mzddm,
kcb_mzddm,
kcb_dbbz,
kcb_xbbz,
kcb_tsbm,
kcb_kcs + kcb_fhs - kcb_fss kfss,
sum(sfb_zds) zds,
sum(sfb_fss) zfss
FROM ddml, kcb, sfb, zdpc, qxhtsbm, tsxxzd
WHERE ddml_mlbh = zdpc_bh
AND sfb_zddm = ddml_zddm
AND tsxx_tsbm = kcb_tsbm
AND sfb_jcd = '370130'
AND kcb_jcd = '370130'
AND ddml_sjdm = qxhtsbm_zdqh || qxhtsbm_zdxh
AND kcb_tsbm = qxhtsbm_tsbm
AND (kcb_kcs + kcb_fhs - kcb_fss) > 0
GROUP BY sfb_zddm,
tsxx_sm,
kcb_kcs,
kcb_fhs,
kcb_fss,
tsxx_dj,
ddml_mzddm,
kcb_mzddm,
kcb_dbbz,
kcb_xbbz,
kcb_tsbm
HAVING SUM(sfb_zds) - SUM(sfb_fss) > 0
ORDER BY zds desc, kcb_tsbm, kfss desc, sfb_zddm;

--select 后面的---sum之前的字段,应和group by的字段保持一致!!!请楼主自已改一下。




[Quote=引用楼主 zhoujia0983 的帖子:]
我写的一个sql语句
SELECT sfb_zddm ,tsxx_sm,tsxx_dj,kcb_dbbz*kcb_xbbz jcs,ddml_mzddm,kcb_mzddm,kcb_dbbz,kcb_xbbz,kcb_tsbm,kcb_kcs+kcb_fhs-kcb_fss kfss,sum(sfb_zds) zds,sum(sfb_fss) zfss FROM ddml,kcb,sfb,zdpc,qxhtsbm,tsxxzd WHERE ddml_mlbh = zdpc_bh AND sfb_zddm = ddml_zddm AND tsxx_tsbm=kcb_tsbm AND sfb_jcd = '370130' AND kcb_jcd= '370130' AND ddml_sjdm = qxhtsbm_zdqh||qxhtsbm_zdxh AND kcb_tsb…
[/Quote]
gisinfo 2008-11-06
  • 打赏
  • 举报
回复
告诉你一个ORACLE执行的规则

从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.

ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

你的数据具体什么样子你晓得
按照我的规则改吧
ejoe313 2008-11-06
  • 打赏
  • 举报
回复
这么复杂啊

建议使用视图,理清关系
gdqsh 2008-11-06
  • 打赏
  • 举报
回复
看的有点晕
sxtaj 2008-11-06
  • 打赏
  • 举报
回复
出过类似问题,顺序不对。

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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