Java 准备好的语句如何提高性能

Java 准备好的语句如何提高性能,java,oracle,jdbc,Java,Oracle,Jdbc,我遇到了下面的语句,它告诉我们JDBC PreparedStatement类的性能改进 如果为每个查询或更新提交新的完整SQL语句,则 对于数据库,数据库必须解析SQL并创建查询 查询计划。通过重用现有的PreparedStatement,您可以重用 SQL解析和查询计划用于后续查询。这 通过减少解析和查询,加快查询执行 计划每次执行的开销 假设我正在创建语句并提供不同的值,同时运行如下查询: String sql = "update people set firstname=? , lastn

我遇到了下面的语句,它告诉我们JDBC PreparedStatement类的性能改进

如果为每个查询或更新提交新的完整SQL语句,则 对于数据库,数据库必须解析SQL并创建查询 查询计划。通过重用现有的PreparedStatement,您可以重用 SQL解析和查询计划用于后续查询。这 通过减少解析和查询,加快查询执行 计划每次执行的开销

假设我正在创建语句并提供不同的值,同时运行如下查询:

String sql = "update people set firstname=? , lastname=? where id=?";

PreparedStatement preparedStatement =
        connection.prepareStatement(sql);

preparedStatement.setString(1, "Gary");
preparedStatement.setString(2, "Larson");
preparedStatement.setLong  (3, 123);

int rowsAffected = preparedStatement.executeUpdate();

preparedStatement.setString(1, "Stan");
preparedStatement.setString(2, "Lee");
preparedStatement.setLong  (3, 456);

int rowsAffected = preparedStatement.executeUpdate();
然后,我仍然可以获得性能优势,因为我正在尝试设置不同的值,这样我就可以确定生成的最终查询是基于值更改的


你能确切地解释一下我们什么时候获得绩效福利吗?值是否也应该相同?

当您使用预编译语句(即预编译语句)时,DB一旦获得该语句,就会编译并缓存该语句,以便可以使用最后编译的语句连续调用同一语句。因此,它是为连续调用而预编译的

在运行时提供变量的地方,通常使用带有绑定变量的prepared语句。现在,对于准备好的语句的连续执行,您可以提供不同于以前调用的变量。从DB的角度来看,它不必每次编译语句,只需在rum时插入绑定变量。所以速度变快了

预处理语句的其他优点是可以防止SQL注入攻击


因此,当您使用预编译语句(即预编译语句)时,值不必相同,只要DB获得该语句,它就会编译并缓存该语句,以便可以使用最后编译的语句连续调用同一语句。因此,它是为连续调用而预编译的

在运行时提供变量的地方,通常使用带有绑定变量的prepared语句。现在,对于准备好的语句的连续执行,您可以提供不同于以前调用的变量。从DB的角度来看,它不必每次编译语句,只需在rum时插入绑定变量。所以速度变快了

预处理语句的其他优点是可以防止SQL注入攻击


因此,值不必相同,尽管SQL不是脚本语言,而是一种“编译”语言并不明显。而这本汇编又叫《阿卡》。优化和硬解析是一项非常详尽的任务。Oracle有很多工作要做,它必须解析查询、解析表名、验证访问权限、执行一些代数转换,然后必须找到有效的执行计划。Oracle(以及其他数据库)只能连接两个表,不能更多。这意味着,当您在SQL中连接多个表时,Oracle必须逐个连接它们。i、 e.如果在查询中加入
n
表,则至少可以有
n可能的执行计划。默认情况下,Oracle在搜索“最佳”(而非最佳)执行计划时最多只能进行8000次排列

因此编译(硬解析)可能比查询执行本身更详尽。为了节省资源,Oracle在称为库缓存的内存结构中的会话之间共享执行计划。这里可能会出现另一个问题,太多解析需要独占访问共享资源。 因此,如果您进行了太多(硬)解析,您的应用程序将无法扩展—会话将相互阻塞

另一方面,有些情况下绑定变量没有帮助。 想象一下这样一个问题:

update people set firstname=? , lastname=? where group=? and deleted='N'
由于列
deleted
已编制索引,并且Oracle知道有98%的值='Y',只有2%的值='N',因此将推断在列
deleted
中使用和编制索引。如果在
deleted
列的条件中使用bind变量,Oracle无法找到有效的执行计划,因为它还依赖于编译时未知的输入。
(注:由于11g,绑定变量窥视更为复杂)

虽然不明显,但SQL不是脚本语言,而是一种“编译”语言。而这本汇编又叫《阿卡》。优化和硬解析是一项非常详尽的任务。Oracle有很多工作要做,它必须解析查询、解析表名、验证访问权限、执行一些代数转换,然后必须找到有效的执行计划。Oracle(以及其他数据库)只能连接两个表,不能更多。这意味着,当您在SQL中连接多个表时,Oracle必须逐个连接它们。i、 e.如果在查询中加入
n
表,则至少可以有
n可能的执行计划。默认情况下,Oracle在搜索“最佳”(而非最佳)执行计划时最多只能进行8000次排列

因此编译(硬解析)可能比查询执行本身更详尽。为了节省资源,Oracle在称为库缓存的内存结构中的会话之间共享执行计划。这里可能会出现另一个问题,太多解析需要独占访问共享资源。 因此,如果您进行了太多(硬)解析,您的应用程序将无法扩展—会话将相互阻塞

另一方面,有些情况下绑定变量没有帮助。 想象一下这样一个问题:

update people set firstname=? , lastname=? where group=? and deleted='N'
由于列
deleted
已编制索引,并且Oracle知道有98%的值='Y',只有2%的值='N',因此将推断在列
deleted
中使用和编制索引。如果在
deleted
列的条件中使用bind变量,Oracle无法找到有效的执行计划,因为它还依赖于编译时未知的输入。 (注:由于11g,绑定v更为复杂