sql 语句如何优化

didoleo 2006-05-10 07:09:14
select a. *, m.amount
from tableA a,
(
select b.fieldD, sum(c.total_amount) amount
from tableA b, tableB c
where b.fieldC = 100 and
b.fieldA in ('AA', 'BB', 'CC', 'DD', 'EE', 'FF') and
b.fieldId = c.fieldId
group by b.fieldD
) m
where a.fieldC = 100 and a.fieldD = m.fieldD and
a.fieldA = 'GG'


这句sql当中对同一个表扫描了两次,所以效率太低,有什么办法可以避免这种写法?
tableA,tableB 是主从表关系。
请不要用sql server 中太特殊的语法,因为要用到oracle中。
在oracle中无人回答。

...全文
436 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
bugchen888 2006-05-12
  • 打赏
  • 举报
回复
贴出执行计划.
十一月猪 2006-05-12
  • 打赏
  • 举报
回复
in 会不会降低速度
子陌红尘 2006-05-11
  • 打赏
  • 举报
回复
Oracle支持分区表,对大表分区如何?
didoleo 2006-05-11
  • 打赏
  • 举报
回复
表的结构重发一下.
tableA:
ta_id cust_id status_desc campaign_plan_id
1 001 OCC 100
2 001 2M 100
3 002 2M 100
4 003 OCC 100
5 003 OCC 100
6 001 2M 100

tableB:
tb_id ta_id product_id total_amount
1 2 005 200.00
2 3 006 600.00
3 6 009 900.00
昵称被占用了 2006-05-11
  • 打赏
  • 举报
回复
oracle 里可以
select b.fieldD,..., sum(c.total_amount) amount
...
group by b.fieldD
吗?

可以这样就方便些


didoleo 2006-05-11
  • 打赏
  • 举报
回复
Yang_(扬帆破浪) 有道理。 exists 可以试一下。

但group by b.fieldD,...会让金额细化了。我只要金额按cust_id 来group by 就可以了。

还是对我有启发的。
Yang_ 2006-05-11
  • 打赏
  • 举报
回复
我说的是说
“那我现在想知道作过预期登记的(OCC)的这些客户当中哪些最终真的作正式登记了,并且要知道正式登记情况下他购买的产品金额是多少。


能否变换成

“那我现在想知道正式登记的客户当中哪些作过预期登记的(OCC),并且要知道正式登记情况下他购买的产品金额是多少。


这里换了主体,关键是能不能换,换过来的效率我想应该能高些,不知道oracle对exists的处理机制能否支持
Yang_ 2006-05-11
  • 打赏
  • 举报
回复
因为从你的描述看,a.*实际是预约客户的所有信息,但是一般来说预约客户的所有信息和它对应的正式客户的所有信息应该是正式客户的所有信息更准确

也许你的语句可以简化为

select b.fieldD,..., sum(c.total_amount) amount
from tableA b, tableB c
where b.fieldC = 100 and
b.fieldA in ('AA', 'BB', 'CC', 'DD', 'EE', 'FF') and
b.fieldId = c.fieldId
and exists (
select 1 from tableA a
where a.fieldC = 100 and a.fieldD = b.fieldD and
a.fieldA = 'GG'
)
group by b.fieldD,...

Yang_ 2006-05-11
  • 打赏
  • 举报
回复
出来的结果必须要有a.*吗?

artoksxb 2006-05-11
  • 打赏
  • 举报
回复
学习!
ashzs 2006-05-11
  • 打赏
  • 举报
回复

表设计是最影响性能的关键点了。如果索引建立的合理还是不能解决问题。表设计不能加以改动。那么只有从平台角度考虑了。你有权限启用实体化视图吗?有权限要求改善硬件环境吗?如果这些都做不到。估计提高的可能性很小了。
didoleo 2006-05-11
  • 打赏
  • 举报
回复
to ashzs((可以包含中文字符))

索引该用的都用上了,索引也不是越多越好的。


//status_desc这个字段最好拆成多个字段(根据你的登记状态的种类:2M、OCC、12+、12-)这样将会使多条记录合成一条!

呵呵~~,是啊,能这样真的好啊。sql是好写了,但是以后有新的状态出来,要再加字段吗?

因为我不是设计人员。表结构一般不能动。如果为了这个查询改表结构会牵动很多人的代码要变动,代价会很大。
  • 打赏
  • 举报
回复
性能优化贴,关注!
lsfw 2006-05-11
  • 打赏
  • 举报
回复
要确认你的Oracle用索引了么?
有些情况下是不用索引的,即使你建立了索引。
我知道涉及隐性类型转换时候索引就不管用。
ashzs 2006-05-11
  • 打赏
  • 举报
回复
首先,你以前建立的索引使用上了吗?你要看看执行计划!如果没有用上,是没有作用的!
在oracle中启用执行计划:
SQL> @?/rdbms/admin/utlxplan.sql
SQL> @?/sqlplus/admin/plustrce.sql
SQL> grant plustrace to public
SQL> set autotrace on
SQL> your sql...

其次,看了你的表结构。感觉可以从tableA下点功夫。
2M、OCC、12+、12-这几种记录可能只是在各自的记录时间上不同,其他的字段信息大体都应该是相同的,status_desc这个字段最好拆成多个字段(根据你的登记状态的种类:2M、OCC、12+、12-)这样将会使多条记录合成一条!然后将登记的更改时间(如果需要的话)分成几个字段。这样将大幅度的减少记录数,较少连接查询时的循环次数,提高效率!

第二种需要变更幅度较大,建议还是通过索引来提高效率。
云中客 2006-05-11
  • 打赏
  • 举报
回复
都是高人,俺只好学习学习了
pratte 2006-05-11
  • 打赏
  • 举报
回复
领教了,to zjcxc(邹建) ,ashzs((可以包含中文字符)) ,收教了,高人!!我佩服了
simonhehe 2006-05-11
  • 打赏
  • 举报
回复
学习ing....
antiking 2006-05-11
  • 打赏
  • 举报
回复
mark
aniude 2006-05-10
  • 打赏
  • 举报
回复
学习
加载更多回复(12)

34,587

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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