Mic*_*l-O 3 oracle oracle-11g-r2 plsql
我目前正在检查我们部门所有数据库用户的 SQL 代码是否没有使用绑定变量。我们确实在一段时间内遇到了 ORA-04031 错误。
现在,我非常清楚在何处使用它们,但我不确定这应该走多远。现在,我是否必须用绑定变量替换所有文字?
例如:
select 1 from t1 ; => select :one from table t;
Run Code Online (Sandbox Code Playgroud)
或者
select c1, c2, from t2 where id = :id and status = 2 =>
select c1, c2, from t2 where id = :id and status = :two
Run Code Online (Sandbox Code Playgroud)
或者
select * from t3 where c3 > :value and exists (select 1 from t4 where <some condition>) =>
select * from t3 where c3 > :value and exists (select :one from t4 where <some condition>)
Run Code Online (Sandbox Code Playgroud)
这同样适用于 DML。
我的直觉是,一切都必须是一个绑定变量才能实现最佳性能。
在您可能实际更改传入值的任何位置使用绑定变量。
例如,EXISTS
在第三个示例中的子句中使用绑定变量可能没有意义,因为任何人似乎都不太可能想要为该EXISTS
子句传入不同的常量。
在您的第二个示例中,假设应用程序可能希望针对不同的id
andstatus
值运行此查询,使用绑定变量而不是硬编码状态可能确实有意义。另一方面,如果代码只status
为这个查询传入2 的值,那么使用绑定变量可能没有意义。假设它status
不是均匀分布的,你最好向优化器提供你总是会使用status
2的信息,而不是试图依靠绑定变量偷看来向优化器提供该信息。
如果该值永远不会改变——即,如果status
第二个查询中的 始终为 2——则您可以根据需要多次执行该查询,并且它只会在v$sql
或 中出现一次v$sqlarea
。就我而言,我将执行查询 10 次
SQL> ed
Wrote file afiedt.buf
1* select * from v$sql where sql_text like '%jc_bind_test%'
SQL> select /* jc_literal_test */ count(*)
2 from emp
3 where ename = 'KING';
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
SQL> /
COUNT(*)
----------
1
Run Code Online (Sandbox Code Playgroud)
从v$sql
or v$sqlarea
,您将只看到具有硬编码文字的查询的一行。该行将显示查询执行了 10 次
SQL> ed
Wrote file afiedt.buf
1* select sql_text, executions, loaded_versions, parse_calls from v$sqlarea where sql_text like '%jc_literal_test%'
SQL> /
SQL_TEXT EXECUTIONS LOADED_VERSIONS PARSE_CALLS
---------------------------------------- ---------- --------------- -----------
select * from v$sql where sql_text like 1 1 1
'%jc_literal_test%'
select sql_text, executions, loaded_vers 5 1 5
ions, parse_calls from v$sql where sql_t
ext like '%jc_literal_test%'
select sql_text, executions, loaded_vers 1 1 1
ions, parse_calls from v$sqlarea where s
ql_text like '%jc_literal_test%'
select /* jc_literal_test */ count(*) 10 1 10
from emp where ename = 'KING'
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1458 次 |
最近记录: |