sqplus:以块的形式检索结果(在循环中更新ROWNUM)

时间:2016-02-21 11:00:52

标签: oracle select subquery sqlplus rownum

我真的很擅长使用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的了解非常有限),所以如果有人可以帮助我使用连接或任何其他方法更有效地重写它,那也可以。

我非常感谢你提供任何帮助。我已经被困在这几天了,而且我无法确定合适的解决方案。

谢谢!

1 个答案:

答案 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** ;