gpt4 book ai didi

java - PreparedStatement 查询中参数化常量的性能后果

转载 作者:行者123 更新时间:2023-11-30 06:47:43 26 4
gpt4 key购买 nike

当使用 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: 使用 rownum 值被参数化的 qry1 与 rownum 常量的 qry2 相比,是否有任何 Oracle 服务器性能优势(查询编译、缓存等)值是硬编码的?

问题 2: 忽略非性能方面的考虑(例如 SQL 注入(inject)、可读性等),Oracle 服务器是否有任何性能优势(查询编译、缓存、等)到在 qry3 上使用 qry2(其中 col2 的值是显式附加,而不是参数化)。

最佳答案

答案 1: 与 qry2(具有合理绑定(bind)变量的查询)相比,使用 qry1(软编码查询)没有性能优势。

绑定(bind)变量通过减少查询解析来提高性能;如果绑定(bind)变量是常量,则无需避免额外的解析。

(可能有一些奇怪的例子,其中添加额外的绑定(bind)变量提高了一个特定查询的性能。与任何预测程序一样,偶尔如果您向 Oracle 优化器提供错误信息,结果会更好。但理解这一点很重要那些是异常(exception)情况。)

答案 2: 与 qry3(硬编码查询)相比,使用 qry2(具有合理绑定(bind)变量的查询)有许多性能优势。

绑定(bind)变量允许 Oracle 重复使用大量进入查询解析(查询编译)的工作。例如,对于每个查询,Oracle 需要检查用户是否有权查看相关表。使用绑定(bind)变量,只需为查询的所有执行执行一次。

绑定(bind)变量还允许 Oracle 使用一些仅在第 N 次运行后才会出现的额外优化技巧。例如,Oracle 可以使用基数反馈来改进查询的第二次执行。当 Oracle 在计划中出错时,例如,如果它估计一个连接将产生 1 行,而实际上它会产生 100 万行,它有时会记录该错误并使用该信息来改进下一次运行。如果没有绑定(bind)变量,下一次运行将有所不同,并且无法修复该问题 错误。

绑定(bind)变量还允许许多不同的计划管理功能。有时,DBA 需要在不更改查询文本的情况下更改执行计划。如果查询文本不断变化,SQL 计划基线、配置文件、大纲和 DBMS_ADVANCED_REWRITE 等功能将不起作用。

另一方面,在一些合理的情况下,最好对查询进行硬编码。有时,分区修剪等 Oracle 功能无法理解表达式,它有助于对值进行硬编码。对于大型数据仓库查询,如果查询无论如何都要运行很长时间,那么额外的时间来解析查询可能是值得的。

(缓存不太可能影响这两种情况。语句的结果缓存很少见,Oracle 更有可能只缓存语句中使用的表的 block 。缓冲区缓存可能不关心这些 block 是否是由一个语句多次访问或由多个语句一次访问)

关于java - PreparedStatement 查询中参数化常量的性能后果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45559183/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com