使用 JDBC的PreparedStatements 查询 Oracle 时,请考虑以下事项:
String qry1 = "SELECT col1 FROM table1 WHERE rownum=? AND col2=?";
String qry2 = "SELECT col1 FROM table1 WHERE rownum=1 AND col2=?";
String qry3 = "SELECT col1 FROM table1 WHERE rownum=1 AND col2=" + someVariable ;
逻辑规定 rownum的值总是一个常数(在本例中为1)。虽然 col2的值是变化的变量。
问题1: 是否有任何Oracle服务器性能优势(查询编译,缓存等)使用qry1,其中rownum值参数化,超过qry2,其中rownum&# 39; s常数值是硬编码的吗?
问题2: 忽略非性能注意事项(例如SQL注入,可读性等),是否有任何Oracle服务器性能优势(查询编译,缓存,等)使用qry2而不是qry3(其中col2的值显式附加,未参数化)。
答案 0 :(得分:4)
答案1: 使用qry1(软编码查询)而不是qry2(具有合理绑定变量的查询)没有性能优势。
绑定变量通过减少查询解析来提高性能;如果绑定变量是常量,则不需要额外的解析。
(可能有一些奇怪的例子,添加额外的绑定变量可以提高一个特定查询的性能。与任何预测程序一样,有时如果向Oracle优化器提供错误信息,结果会更好。但是它会更好。重要的是要了解那些是例外情况。)
答案2: 与qry3(硬编码查询)相比,使用qry2(具有合理绑定变量的查询)有许多性能优势。
绑定变量允许Oracle重复使用进行查询解析(查询编译)的大量工作。例如,对于每个查询,Oracle需要检查用户是否有权查看相关表。使用绑定变量只需要对查询的所有执行执行一次。
绑定变量还允许Oracle使用仅在第N次运行后发生的一些额外优化技巧。例如,Oracle可以使用基数反馈来改进查询的第二次执行。当Oracle在计划中出错时,例如,如果它估计连接在真正产生100万时会产生1行,它有时会记录该错误并使用该信息来改善下一次运行。如果没有绑定变量,下一次运行将会有所不同,并且无法解决这个问题 错误。
绑定变量还允许许多不同的计划管理功能。有时,DBA需要在不更改查询文本的情况下更改执行计划。如果查询文本不断变化,SQL计划基线,配置文件,大纲和DBMS_ADVANCED_REWRITE等功能将无法使用。
另一方面,在一些合理的情况下,对查询进行硬编码会更好。有时像分区修剪这样的Oracle功能无法理解表达式,它有助于对值进行硬编码。对于大型数据仓库查询,如果查询将要运行很长时间,那么解析查询的额外时间可能是值得的。
(缓存不太可能影响任何一种情况。语句的结果缓存很少,Oracle更有可能只缓存语句中使用的表的块。缓冲区缓存可能并不关心如果这些块多次被一个语句访问,或者一次被多个语句访问)