sql类似这样:
INSERT INTO TABLE RS
SELECT ...FROM
 (SELECT ...FROM 
  (SELECT ... FROM ...) A,
  (SELECT ... FROM (SELECT ... FROM ...)) B
   TABLE C,
   TABLE D
   WHERE...
  ) E, TABLE F, TABLE G
WHERE ...SELECT ...FROM
 (SELECT ...FROM 
  (SELECT ... FROM ...) A,
  (SELECT ... FROM (SELECT ... FROM ...)) B
   TABLE C,
   TABLE D
   WHERE...
  ) E, TABLE F, TABLE G
WHERE ...第一段sql语句就比第二段多了INSERT INTO TABLE RS而已
因为实际sql涉及到业务逻辑,所以也不敢贴出来。
目前遇到问题是我单纯执行第二段sql很快,几秒钟数据就出来了。
但是想把查询出来的数据插入另外一张表就很慢了,几分钟都没出来结果。查看了解释计划:
select语句:
hash join
 hash join
  hash join
   hash join
...insert into语句:
nested loop
 nested loop
  nested loop
   nested loop
...我奇怪的是为什么同样的select语句,没加insert into是用hash join,加了之后却用nested loop呢??
实际的结果也是单纯select很快, 而加了insert into后却很慢。。
上面sql语句子查询的数据量一般为几千,几万,几十万
最后查询结果结果根据时段的不同最多为两百万条记录。
  

解决方案 »

  1.   

    可能你的查询只显示了前面的一部分记录,并没有取出所有记录。
    而insert肯定会取出所有记录插入表。你可以把最外层改成select count(*) from (select ....);记录比较
    两个语句的效率。至于执行计划,你先搜集一下查询语句中涉及到的表的统计数据
    再比较一下执行计划。如果有区别,可以再作一个SQL Trace跟踪一下。
      

  2.   

    select 只是从表中查询数据,并不会生成undo和redo
    而insert 则会生成大量的undo和redo:
    insert 生成的undo信息能够取消insert
    insert 生成的redo信息可以在出现故障的情况下使insert再次发生
      

  3.   

    我测试过只抽取一天的数据,数据量很小,只有几千条记录,insert into也是很慢。
    后面我直接用minus过滤了所有数据,就算插入0行记录也是很慢。select count(*)的执行计划和select ...的一样。用的也是hash join
      

  4.   

    我用一段没用那么多嵌套查询的sql测试了一下。发现select部分的执行计划和加了insert into后的执行计划差别不大。都是用hash join。所以不知道现在要怎么优化这段sql。虽然查询速度没问题,但是insert into的速度太慢了,抽取一天的数据几分钟都没出来。各位能不能指点一下呢?
      

  5.   

    几种可能:
    1、回滚段太小
    2、RS表上索引或校验台多
    3、RS表本身碎片比较多。比较慢。
      

  6.   

    是不是因为生成了大量的undo和redo信息导致加了insert into的select部分sql的执行计划也改变了?
    我现在困惑的是两段sql的select部分是一样的,但是执行计划为什么差异那么大。
    不知道是什么原因导致执行计划从hash join变成了nested loops。
      

  7.   

    1.回滚段是否太小这个我不太清楚。
    2.这个表插入操作很频繁,设计时没创建索引。
    3.我修改了上面的sql,把其中一些子查询的数据存入临时表,临时表有创建索引,执行insert into时虽然慢,但是一个月的数据几分钟插入成功。所以我觉得应该不关rs表的问题。只是我不想采用临时表这种方式,因为需要改动程序。
      

  8.   

    解决了。。
    最内层的子查询中用了一个视图,这个视图是关联五六张表后得到的资料。
    当时是把这张视图换成表,发现两段sql的执行计划就几乎一样了。。具体底层的原理也不明白。最后采用use_hash指定最内层的子查询使用hash join就解决了。。
    谢谢上面几位的回答。。