【问题标题】:How to limit resultset globaly (or by session) in Oracle?如何在 Oracle 中全局(或按会话)限制结果集?
【发布时间】:2012-06-19 18:27:45
【问题描述】:

我尝试限制结果集的大小,而不必更改应用程序中的每个 SQL 语句(至少例如)。因此,在每个查询中添加ROWNUM 子句不是一种选择。

我或多或少在寻找一些全局参数,或者至少是一个会话参数(如 SQLServer 中的SET ROWCOUNT)。

应用程序使用 JDBC 资源池连接到 Oracle,因此我可以在 SQL 初始化 JDBC 池中设置会话范围的参数。

【问题讨论】:

    标签: java sql oracle jakarta-ee oracle11g


    【解决方案1】:

    您是否尝试过使用Statement.setMaxRows method?这是一种标准的 JDBC 方法,它会在获取指定的最大数量后静默删除行。

    但是,从性能的角度来看,实际修改发送到数据库的查询可能会为您提供更好的服务。如果您按照@MK 的建议进行操作,您将告诉优化器您只会获取 N 行。这可能允许优化器选择更有效的计划。

    【讨论】:

    • 对,问题在于 a) 数据库仍然需要找到所有行,只是 JDBC 删除了它们,b) 他必须手动查找查询所在的每个位置执行。
    • @MK - Oracle 通常只在您获取结果时实现结果(当然,除非它必须获取所有数据才能在返回第一行之前对其进行排序) .因此,如果您从不获取超过前 N 行的内容,通常可以节省执行时间。当然,如果您告诉 Oracle 您只需要使用ROWNUM 子句的前 N ​​行,那么通常不会花费太多时间。理论上,JDBC 驱动程序可以通过静默添加WHERE rownum <= N 子句来实现setMaxRows——不知道Oracle JDBC 驱动程序是否真的这样做了。
    • 有趣。除了 setMaxRows 之外,我当然见过有人手动将 WHERE rownum 限制添加到 Oracle 查询中,但我从未对其进行基准测试。
    • 这似乎是最好的方法,但有很大的缺点@MK。建议:必须手动查找所有查询(并使其可配置)。我对 Oracle 没有这样一个会话范围的属性感到非常失望。
    【解决方案2】:

    我怀疑没有办法做到这一点。您可以创建一个 AOP 建议,该建议将通过使用

    包装查询来修改每个 executeQuery() 调用
    "select * from ( " + origQuery + " ) where ROWNUM <= 5"
    

    但我希望这是我们正在谈论的临时或测试的事情。

    【讨论】:

    • 动态修改所有SQL语句需要小心。至少在一种情况下这种方法不起作用。例如,select * from (select 1 a, 2 a from dual); 将导致 ORA-00918: column ambiguously defined。并且更改 SQL 语句可能会破坏一些性能调优方法,例如存储大纲。
    • @jonearles 同意,请参阅我关于这是临时或测试的评论:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多