我真的很擅长使用sqlplus,所以如果这是一个愚蠢的问题,我很抱歉。
我有一个很长时间运行的表单查询:
SELECT columnA
from tableA
where fieldA in (
(select unique columnB
from tableB
where fieldB in
(select columnC
from tableC
where fieldC not in
(select columnD
from tableD
where x=y
and a=b
and columnX in
(select columnE
from tableE
where p=q)))
and columnInTableB = <some value>
and anotherColumnInTableB = <some other value>
and thirdColumnInTableB IN (<set of values>)
and fourthColumnInTableB like <some string>);
每个表都有大约15-30列和不同的行数。 TableB是最大的,总共有大约500万行。表A-E各有500,000-1,000万行。
我尝试了几种方法:
1)按原样运行此查询:
此查询运行的时间很长,我收到错误 - ORA-01555:快照太旧:回滚段号&lt;&gt;名称&lt;&gt;
我做了一些研究,发现了类似的东西: ORA-1555: snapshot too old: rollback segment number
但是,我没有权限更改撤消细分。
2)我使用with ...重新编写查询,但后来我得到了错误: 无法通过&lt;&gt;扩展临时段在表空间TEMP中
同样,我找到了有关如何解决此错误的解释,但我没有权限扩展临时段。
运行时间最长的查询是:
(select unique columnB
from tableB ...
在最坏的情况下,and fourthColumnInTableB like <some string>);
匹配tableB中大约300万个条目。
有人建议我以较小的块运行查询。
我想到的一种方法是检索长时间运行的子查询的数据(
(select unique columnB
from tableB ...
)
in chunk(使用ROWNUM建议here。 我的问题是:
我不确切地知道这个子查询有多少可能匹配。我可以动态设置ROWNUM来检索块中的数据吗?
如果是的话,请你给我一个示例,说明while循环必须是什么样的,以及如何确定结果集何时耗尽?
我找到的一个选项是检查while @@ROWCOUNT > 0
或使用:
while exists (query)
但是,我仍然不确定如何编写循环以及如何使用变量(?)来动态设置ROWNUM。
基本上,我想知道我能否做到:
SELECT columnA
from tableA
where fieldA in (
while all results have not been fetched:
select *
from
(select a.*, rownum rnum
from
(select unique columnB
from tableB
where fieldB in
(select columnC
from tableC
where fieldC not in
(select columnD
from tableD
where x=y
and a=b
and columnX in
(select columnE
from tableE
where p=q)))
and columnInTableB = <some value>
and anotherColumnInTableB = <some other value>
and thirdColumnInTableB IN (<set of values>)
and fourthColumnInTableB like <some string>) a
where rownumm <= i) and rnum >= i);
update value of i here (?) so that the loop can repeat
如何更新&#39; i&#39;的价值? for rownum / rnum在某个循环中动态地检索结果(例如,10000),直到结果集用完为止?
此外,while循环应该是什么样的?
我也不知道如何使用连接重写它(我对sql的了解非常有限),所以如果有人可以帮助我使用连接或任何其他方法更有效地重写它,那也可以。
我非常感谢你提供任何帮助。我已经被困在这几天了,而且我无法确定合适的解决方案。
谢谢!
答案 0 :(得分:0)
1)尝试删除UNIQUE / DISTINCT子句。它应该在内存中排序和临时段。
2)尝试应用'rownum&lt; x_rows'过滤器,最后,不限制任何行到客户端并减少IO。
SELECT columnA
FROM tableA
WHERE fieldA IN (
(SELECT **UNIQUE** columnB
FROM tableB
WHERE fieldB IN
(SELECT columnC
FROM tableC
WHERE fieldC NOT IN
(SELECT columnD
FROM tableD
WHERE x =y
AND a =b
AND columnX IN
(SELECT columnE FROM tableE WHERE p=q
)
)
)
AND columnInTableB = <SOME value>
AND anotherColumnInTableB = <SOME other value>
AND thirdColumnInTableB IN (<
SET OF VALUES >)
AND fourthColumnInTableB LIKE <SOME string>
)
**ROWNUM < 50** ;