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语句子查询的数据量一般为几千,几万,几十万
最后查询结果结果根据时段的不同最多为两百万条记录。
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语句子查询的数据量一般为几千,几万,几十万
最后查询结果结果根据时段的不同最多为两百万条记录。
而insert肯定会取出所有记录插入表。你可以把最外层改成select count(*) from (select ....);记录比较
两个语句的效率。至于执行计划,你先搜集一下查询语句中涉及到的表的统计数据
再比较一下执行计划。如果有区别,可以再作一个SQL Trace跟踪一下。
而insert 则会生成大量的undo和redo:
insert 生成的undo信息能够取消insert
insert 生成的redo信息可以在出现故障的情况下使insert再次发生
后面我直接用minus过滤了所有数据,就算插入0行记录也是很慢。select count(*)的执行计划和select ...的一样。用的也是hash join
1、回滚段太小
2、RS表上索引或校验台多
3、RS表本身碎片比较多。比较慢。
我现在困惑的是两段sql的select部分是一样的,但是执行计划为什么差异那么大。
不知道是什么原因导致执行计划从hash join变成了nested loops。
2.这个表插入操作很频繁,设计时没创建索引。
3.我修改了上面的sql,把其中一些子查询的数据存入临时表,临时表有创建索引,执行insert into时虽然慢,但是一个月的数据几分钟插入成功。所以我觉得应该不关rs表的问题。只是我不想采用临时表这种方式,因为需要改动程序。
最内层的子查询中用了一个视图,这个视图是关联五六张表后得到的资料。
当时是把这张视图换成表,发现两段sql的执行计划就几乎一样了。。具体底层的原理也不明白。最后采用use_hash指定最内层的子查询使用hash join就解决了。。
谢谢上面几位的回答。。