admin

静态与动态SQL

sql

在我的数据库的多个地方,开发人员使用了动态sql而不是静态sql。他们说这是为了提高性能。有人可以告诉我动态sql是否真的可以提高存储过程或plsql块的性能吗?

哪个执行速度更快,为什么?
1。

begin  
    execute immediate 'delete from X';  
end;

2。

begin  
    delete from X;  
end;

阅读 138

收藏
2021-05-10

共1个答案

admin

您的示例代码非常简单,几乎没有什么区别,但是在那种情况下,静态版本最有可能执行得更好。

使用动态SQL来提高性能的主要原因是,当SQL语句发生重大变化时-
例如,您可以根据系统状态在运行时向WHERE子句添加额外的代码(受子查询限制)在地址上(如果输入了地址等)。

另一个原因是,有时将Bind变量用作参数可能适得其反。

例如,如果您有类似状态字段的内容,则数据分布不均匀(但已建立索引)。

当处理95%的数据时,请考虑以下3条语句

   SELECT col FROM table 
   WHERE status = 'U'-- unprocessed
   AND company = :company

   SELECT col FROM table 
   WHERE status = 'P' -- processed
   AND company = :company

   SELECT col FROM table
   WHERE status = :status
   AND company = :company

在最终版本中,Oracle将选择通用的解释计划。在第一个版本中,它可能决定最好的计划是从状态索引开始(知道“ U”未处理的条目在总数中只占很小的一部分)。

您可以通过不同的静态语句来实现这一点,但是如果您有更复杂的语句(仅需更改几个字符),则动态SQL可能是一个更好的选择。

缺点

相同的动态SQL语句的每次重复都会产生一个软解析,与静态语句相比,这是一个很小的开销,但是仍然是一个开销。

每个NEW sql语句(动态或静态)也会在SGA(共享内存)上产生锁定,并可能导致推出“旧”语句。

一个糟糕但常见的系统设计是,有人使用动态SQL来生成仅随键而异的简单选择-即

SELECT col FROM table WHERE id = 5
SELECT col FROM table WHERE id = 20
SELECT col FROM table WHERE id = 7

各个语句将很快,但是整个系统的性能将下降,因为它会杀死共享资源。

另外-使用动态SQL在编译时捕获错误要困难得多。如果使用PL /
SQL,则会浪费大量的编译时间检查。即使使用JDBC之类的东西(将所有数据库代码都移到字符串中-很好!),您也可以使用预解析器来验证JDBC内容。动态SQL
=仅运行时测试。

开销

立即执行的开销很小-大约是千分之一秒-
但是,如果它在循环内/在每个对象调用一次的方法上等等,它可以加起来。通过替换动态对象,我曾经获得了10倍的速度提高具有生成的静态SQL的SQL。但是,这使代码复杂化,并且仅因为我们需要速度而完成了。

2021-05-10