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

时间:2010-04-23 21:53:33

标签: oracle oracle10g

在处理带有接近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

3 个答案:

答案 0 :(得分:3)

在Oracle 8及更高版本中,您可以create usage profiles控制和限制任何一个会话可以使用的资源。您创建一个配置文件并将其与用户或角色相关联数据库将确保更公平地共享逻辑/物理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时必须执行的硬分析数。

答案 1 :(得分:1)

由于你有3500个绑定变量,它听起来像一个大规模的查询。我会假设查询的复杂性(连接表/视图,子查询等...)比使用这些绑定变量更多地是麻烦制造者。必须检查每个连接的索引(如果有索引)。当第一次提交查询时,必须构建执行计划,听起来Oracle正在窒息。

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

答案 2 :(得分:1)

查询是什么样的?

我想这是一个“列表中的变量”查询,比如,其中id为(: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&#3855830

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

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