具有大量绑定变量的 oracle select 的影响/限制是什么?

发布于 2024-08-30 05:47:13 字数 1143 浏览 5 评论 0原文

在处理具有接近 3500(!!)个绑定变量的 select 语句时,我们的 Oracle 服务器出现了阻塞。

显然,这个选择是由我们无法更改的代码动态构建的。在执行此选择期间,数据库服务器的 CPU 使用率达到 100%,我们的系统几乎停止运行。

我们知道如何重现这个问题。所以我们可以预防这种特殊情况。但我想知道是否有一种方法可以保护数据库(通过配置)免受此类问题的影响。

更新

选择如下所示:

SELECT "FieldOfChar20"
FROM "TableOf111Krows"
WHERE (   "FieldOfChar20" BETWEEN :a0 AND :a1
    OR "FieldOfChar20" BETWEEN :a2 AND :a3
    OR "FieldOfChar20" BETWEEN :a4 AND :a5
    snip snip
    OR "FieldOfChar20" BETWEEN :a290 AND :a291
    OR "FieldOfChar20" BETWEEN :a292 AND :a293
   )
OR (   "FieldOfChar20" IN
          (:a294,
           :a295,
            snip snip
           :a1292,
           :a1293
          )
    OR "FieldOfChar20" IN
          (:a1294,
           :a1295,
           snip snip
           :a2292,
           :a2293
          )
    OR "FieldOfChar20" IN
          (:a2294,
           :a2295,
            snip snip
           :a3292,
           :a3293
          )
    OR "FieldOfChar20" IN
          (:a3294,
           :a3295,
           snip snip
           :a3476,
           :a3477
          )
   )

Oracle 版本为 10.2.0.2

We had our oracle server choking during processing a select statement with close to 3500(!!) bind variables.

This select is, obviously, built dynamically by code that we can't change. During the execution of this select the db server went to 100% cpu usage and our system almost halted.

We know how to reproduce this problem. So we can prevent this specific condition. But I am wondering if there is a way to protect the db ( by configuration) from this type of problems.

Update:

The select looks like that:

SELECT "FieldOfChar20"
FROM "TableOf111Krows"
WHERE (   "FieldOfChar20" BETWEEN :a0 AND :a1
    OR "FieldOfChar20" BETWEEN :a2 AND :a3
    OR "FieldOfChar20" BETWEEN :a4 AND :a5
    snip snip
    OR "FieldOfChar20" BETWEEN :a290 AND :a291
    OR "FieldOfChar20" BETWEEN :a292 AND :a293
   )
OR (   "FieldOfChar20" IN
          (:a294,
           :a295,
            snip snip
           :a1292,
           :a1293
          )
    OR "FieldOfChar20" IN
          (:a1294,
           :a1295,
           snip snip
           :a2292,
           :a2293
          )
    OR "FieldOfChar20" IN
          (:a2294,
           :a2295,
            snip snip
           :a3292,
           :a3293
          )
    OR "FieldOfChar20" IN
          (:a3294,
           :a3295,
           snip snip
           :a3476,
           :a3477
          )
   )

Oracle version is 10.2.0.2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江南月 2024-09-06 05:47:13

在 Oracle 8 及更高版本中,您可以创建控制和限制的使用配置文件任何一个会话可以消耗的资源。您创建一个配置文件并将其与用户或角色关联,数据库将确保更公平地共享逻辑/物理 IO、CPU 和其他有限资源。

配置文件中有趣的部分包括:

[CPU_PER_SESSION           n|UNLIMITED|DEFAULT]     
[CPU_PER_CALL              n|UNLIMITED|DEFAULT]            
[CONNECT_TIME              n|UNLIMITED|DEFAULT]
[IDLE_TIME                 n|UNLIMITED|DEFAULT]
[LOGICAL_READS_PER_SESSION n|UNLIMITED|DEFAULT]  
[LOGICAL_READS_PER_CALL    n|UNLIMITED|DEFAULT]
[COMPOSITE_LIMIT           n|UNLIMITED|DEFAULT]
[PRIVATE_SGA               n [K|M]|UNLIMITED|DEFAULT]

至于绑定变量,我不知道有什么方法可以让数据库或 OCI 客户端限制它们的使用。事实上,绑定变量通常比 SQL 中的嵌入值具有更好的性能(和安全性)。具体来说,减少数据库在执行仅参数值变化的 SQL 时必须执行的硬解析次数。

In Oracle 8 and later, you can create usage profiles that control and limit the resources that any one session can consume. You create a profile and associate it to a user or role and the database will make sure that thing like logical/physical IO, CPU, and other limited resources are shared more equitably.

The interesting bits of a profile include:

[CPU_PER_SESSION           n|UNLIMITED|DEFAULT]     
[CPU_PER_CALL              n|UNLIMITED|DEFAULT]            
[CONNECT_TIME              n|UNLIMITED|DEFAULT]
[IDLE_TIME                 n|UNLIMITED|DEFAULT]
[LOGICAL_READS_PER_SESSION n|UNLIMITED|DEFAULT]  
[LOGICAL_READS_PER_CALL    n|UNLIMITED|DEFAULT]
[COMPOSITE_LIMIT           n|UNLIMITED|DEFAULT]
[PRIVATE_SGA               n [K|M]|UNLIMITED|DEFAULT]

As for bind variables, I'm not aware of any way to have the database or OCI client limit the use of these. In fact, bind variables are generally better for performance (and security) than embedded values in the SQL. Specifically, the reduce the number of hard parses that the database must perform when executing SQL that only varies in the values of parameters.

不离久伴 2024-09-06 05:47:13

由于您有 3500 个绑定变量,这听起来像是一个巨大的查询。我认为查询的复杂性(表/视图上的连接、子查询等)比那些绑定变量更麻烦。必须检查每个连接的索引(如果有索引)。当第一次提交查询时,必须构建执行计划,听起来 Oracle 对此感到窒息。

但是,一旦计划构建完成,它就会存储在内存中并且不需要重建(感谢绑定变量)。所以拥有大量的绑定变量可能并不是一件坏事。

Since you have 3500 bind variables, it sounds like a massive query. I would assume that the complexity of the query (joins on tables / views, subqueries, etc...) would be much more of a troublemaker than having those bind variables. Indexes have to be examined for each join (if there are indexes). When the query is submitted for the first time the execution plan has to be built, and it sounds like Oracle is choking on that.

However, once the plan is built, it is stored in memory and doesn't need to be rebuilt (thanks to the bind variables). So having a large amount of bind variables may not be a bad thing.

云巢 2024-09-06 05:47:13

查询是什么样的?

我猜这是一个“列表中的变量”查询,例如 where id in (:1,:2,:3,.....) 查询?

该应用程序的开发人员应该加入内存集合:

      select  /*+ cardinality(tab 10) */ *  
      from employees, table(:1) tab 
      where employees.id = tab.column_value";

更多信息: http://forums.oracle.com/forums/thread.jspa?messageID=3855830�

绑定数量始终相同还是始终不同?有时3500,有时3499,有时3520...?

如果绑定数量不同,则不会从缓存中检索查询的执行计划。

What does the query look like?

I guess it is a "variable in list" query like where id in (:1,:2,:3,.....) query?

The developers of that app should have joined with a memory collection:

      select  /*+ cardinality(tab 10) */ *  
      from employees, table(:1) tab 
      where employees.id = tab.column_value";

More here: http://forums.oracle.com/forums/thread.jspa?messageID=3855830�

Is the number of binds always the same or is it always different? Sometimes 3500, sometimes 3499, sometimes 3520...?

The execution plan of the query will not be retrieved from the cache if the number of binds differs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文