- 浏览: 21500 次
- 性别:
- 来自: 石家庄
使用绑定提高动态 SQL 性能
由于几个方面的原因,开发人员通常会选择不在 PL/SQL 中使用动态 SQL。一个方面的原因是这样做有风险,因为 SQL 语句到运行时期才解析,所以捕获简单语法错误的难度会更大。此外,很多动态 SQL 的尝试都会带来性能问题,简单编写动态 SQL 的复杂性对动态 SQL 也有负面的影响。
这里给出一个简单的测试,我们使用两个方法将某段范围内的数字插入到一个表中,然后对两种方法进行了对比:
drop table mytest;
create table mytest(i number);
prompt 1) using pure insert
set timing on;
begin
for i in 1..10000 loop
insert into mytest values(i);
end loop;
end;
/
show errors;
set timing off;
truncate table mytest;
prompt 2) using execute immediate
set timing on;
begin
for i in 1..10000 loop
execute immediate 'insert into mytest values('||i||')';
end loop;
end;
/
show errors;
set timing off;
在我的测试中,第二个 PL/SQL 块的运行时间相当于第一个 PL/SQL 块运行时间的六倍。然而,这不是一个公平的比较,因为它违反了动态 SQL 的一个黄金规则:在能够绑定时永远不要串联(concatenation)。固定串联意味着需要解析、分解和执行10000个独立的 SQL 语句。第一个例子中的原生 PL/SQL 插入语句实际上生成一个递归 SQL 语句——'insert into mytest values(:1)'——然后在每次迭代时绑定具体值。
下面是动态 SQL 的一个稍好的对比:
truncate table mytest;
prompt 3) using execute immediate with bind
set timing on;
begin
for i in 1..10000 loop
execute immediate 'insert into mytest values(:i)' using in i;
end loop;
end;
/
show errors;
set timing off;
这段代码的运行时间是第一个块的运行时间的两倍。其速度是第二个 PL/SQL 块运行速度的三倍。然而,动态 SQL 依然占据劣势。execute immediate依然会进行解析,但是它使用 SQL 共享来分解语句。
理想的情况是 PL/SQL 允许我们在 OPEN 过程中创建游标,然后再有一些新的命令允许我们 EXECUTE <cursor> USING……即使在 Oracle 10g 中也没有这样的命令。我已经观察原生动态 SQL 很长时间了,我依然发现在这些情况下它没有DBMS_SQL 强大。
PL/SQL 用户指南警告说DBMS_SQL 的性能没有EXECUTE IMMEDIATE 的性能好,但是让我们自己试一下看看:
truncate table mytest;
prompt 4) using dbms_sql
set timing on;
declare
c integer;
r integer;
begin
c := dbms_sql.open_cursor;
for i in 1..10000 loop
dbms_sql.parse(c,'insert into mytest values('||i||')',dbms_sql.native);
r := dbms_sql.execute(c);
end loop;
dbms_sql.close_cursor(c);
end;
/
show errors;
set timing off;
truncate table mytest;
prompt 5) using dbms_sql with bind
set timing on;
declare
c integer;
r integer;
begin
c := dbms_sql.open_cursor;
dbms_sql.parse(c,'insert into mytest values(:i)',dbms_sql.native);
for i in 1..10000 loop
dbms_sql.bind_variable(c,':i',i);
r := dbms_sql.execute(c);
end loop;
dbms_sql.close_cursor(c);
end;
/
show errors;
set timing off;
第四个例子的问题与第二个例子一样——它使用了串联。这也说明 PL/SQL 手册在这种情况下是对的。第四个例子的运行时间是第一个例子运行时间的七倍。DBMS_SQL 确实比EXECUTE IMMEDIATE 慢,但是EXECUTE IMMEDIATE 依然没有DBMS_SQL 灵活。
第五个例子是一个惊喜——它的完成时间与第一个例子几乎完全相同。它的执行过程几乎与第一个例子完全相同,它的编码难度明显比较大并且更容易出现错误,但是对于很多任务来说,动态 SQL 可能很必要。
更进一步地对比,等效的 Java 存储过程(总是动态的),它的运行时间与原始的 PL/SQL 以及带绑定的DBMS_SQL 几乎相同:
import java.sql.*;
public class dynsql
{
public static void ins() throws SQLException
{
Connection conn
= DriverManager.getConnection("jdbc:default:connection:");
PreparedStatement pstmt
= conn.prepareStatement("insert into mytest values(?)");
for (int i=0;i<10000;i++)
{
pstmt.setInt(1,i);
pstmt.executeUpdate();
}
pstmt.close();
}
}
set timing off;
create or replace procedure dynsql_ins as language java name 'dynsql.ins()';
/
show errors;
truncate table mytest;
set timing on;
exec dynsql_ins;
set timing off;
由于几个方面的原因,开发人员通常会选择不在 PL/SQL 中使用动态 SQL。一个方面的原因是这样做有风险,因为 SQL 语句到运行时期才解析,所以捕获简单语法错误的难度会更大。此外,很多动态 SQL 的尝试都会带来性能问题,简单编写动态 SQL 的复杂性对动态 SQL 也有负面的影响。
这里给出一个简单的测试,我们使用两个方法将某段范围内的数字插入到一个表中,然后对两种方法进行了对比:
drop table mytest;
create table mytest(i number);
prompt 1) using pure insert
set timing on;
begin
for i in 1..10000 loop
insert into mytest values(i);
end loop;
end;
/
show errors;
set timing off;
truncate table mytest;
prompt 2) using execute immediate
set timing on;
begin
for i in 1..10000 loop
execute immediate 'insert into mytest values('||i||')';
end loop;
end;
/
show errors;
set timing off;
在我的测试中,第二个 PL/SQL 块的运行时间相当于第一个 PL/SQL 块运行时间的六倍。然而,这不是一个公平的比较,因为它违反了动态 SQL 的一个黄金规则:在能够绑定时永远不要串联(concatenation)。固定串联意味着需要解析、分解和执行10000个独立的 SQL 语句。第一个例子中的原生 PL/SQL 插入语句实际上生成一个递归 SQL 语句——'insert into mytest values(:1)'——然后在每次迭代时绑定具体值。
下面是动态 SQL 的一个稍好的对比:
truncate table mytest;
prompt 3) using execute immediate with bind
set timing on;
begin
for i in 1..10000 loop
execute immediate 'insert into mytest values(:i)' using in i;
end loop;
end;
/
show errors;
set timing off;
这段代码的运行时间是第一个块的运行时间的两倍。其速度是第二个 PL/SQL 块运行速度的三倍。然而,动态 SQL 依然占据劣势。execute immediate依然会进行解析,但是它使用 SQL 共享来分解语句。
理想的情况是 PL/SQL 允许我们在 OPEN 过程中创建游标,然后再有一些新的命令允许我们 EXECUTE <cursor> USING……即使在 Oracle 10g 中也没有这样的命令。我已经观察原生动态 SQL 很长时间了,我依然发现在这些情况下它没有DBMS_SQL 强大。
PL/SQL 用户指南警告说DBMS_SQL 的性能没有EXECUTE IMMEDIATE 的性能好,但是让我们自己试一下看看:
truncate table mytest;
prompt 4) using dbms_sql
set timing on;
declare
c integer;
r integer;
begin
c := dbms_sql.open_cursor;
for i in 1..10000 loop
dbms_sql.parse(c,'insert into mytest values('||i||')',dbms_sql.native);
r := dbms_sql.execute(c);
end loop;
dbms_sql.close_cursor(c);
end;
/
show errors;
set timing off;
truncate table mytest;
prompt 5) using dbms_sql with bind
set timing on;
declare
c integer;
r integer;
begin
c := dbms_sql.open_cursor;
dbms_sql.parse(c,'insert into mytest values(:i)',dbms_sql.native);
for i in 1..10000 loop
dbms_sql.bind_variable(c,':i',i);
r := dbms_sql.execute(c);
end loop;
dbms_sql.close_cursor(c);
end;
/
show errors;
set timing off;
第四个例子的问题与第二个例子一样——它使用了串联。这也说明 PL/SQL 手册在这种情况下是对的。第四个例子的运行时间是第一个例子运行时间的七倍。DBMS_SQL 确实比EXECUTE IMMEDIATE 慢,但是EXECUTE IMMEDIATE 依然没有DBMS_SQL 灵活。
第五个例子是一个惊喜——它的完成时间与第一个例子几乎完全相同。它的执行过程几乎与第一个例子完全相同,它的编码难度明显比较大并且更容易出现错误,但是对于很多任务来说,动态 SQL 可能很必要。
更进一步地对比,等效的 Java 存储过程(总是动态的),它的运行时间与原始的 PL/SQL 以及带绑定的DBMS_SQL 几乎相同:
import java.sql.*;
public class dynsql
{
public static void ins() throws SQLException
{
Connection conn
= DriverManager.getConnection("jdbc:default:connection:");
PreparedStatement pstmt
= conn.prepareStatement("insert into mytest values(?)");
for (int i=0;i<10000;i++)
{
pstmt.setInt(1,i);
pstmt.executeUpdate();
}
pstmt.close();
}
}
set timing off;
create or replace procedure dynsql_ins as language java name 'dynsql.ins()';
/
show errors;
truncate table mytest;
set timing on;
exec dynsql_ins;
set timing off;
发表评论
-
自定义合计函数
2009-04-21 09:57 784Example: Creating and Using a U ... -
PL/SQL开发中动态SQL的使用之三
2008-11-13 15:56 897动态SQL和PL/SQL的EXECUTE IMMEDIATE选 ... -
PL/SQL开发中动态SQL的使用之二
2008-11-13 15:54 1155基于Oracle的高性能动态SQL程序开发 1. 静态SQ ... -
PL/SQL开发中动态SQL的使用之一
2008-11-13 15:53 980PL/SQL开发中动态SQL的使 ... -
Oracle数据库中分区表的操作方法
2008-11-13 15:32 931Oracle数据库中分区表的操作方法 摘要:在大量业务数据 ... -
存储过程调试信息打印
2008-11-13 15:02 1689SET serveroutput on size 100000 ... -
SQL语句优化
2008-11-13 14:48 1865我们要做到不但会写SQL,还要做到写出性能优良的SQL,以下为 ... -
常用数据字典
2008-11-10 12:11 638以下表格中收集了Oracle数据字典中几乎所有的视图或 ... -
创建Job
2008-11-10 12:09 765variable job1 number; begin ... -
优化ORACLE性能
2008-11-10 12:05 973前言 使用oracle有两年了,积累的一些东西,与大家探讨一下 ... -
重建TEMP表空间
2008-11-10 12:02 1193startup --启动数据库 create ... -
导入导出
2008-11-10 12:00 761脚本$ORACLE_HOME\ora92\rdbms\admi ... -
利用database link实现跨库查询
2008-11-10 11:57 1373create database link dbLink ...
相关推荐
12. **调试和错误诊断**:最后,手册会介绍如何使用Oracle提供的调试工具和技巧来追踪和解决PL/SQL程序中的问题。 这份"PL/SQL最新中文手册"对于任何想要深入理解并有效利用PL/SQL进行Oracle数据库开发的人来说,都...
在"Oracle Database 12c PL/SQL开发指南(第7版)"这本书中,作者深入浅出地介绍了如何使用PL/SQL进行数据库开发。这本书涵盖了许多关键知识点,包括但不限于: 1. **PL/SQL基础**:PL/SQL的基础语法,如变量声明、...
标题中提到的“PL/SQL开发文档1”,说明本文档是关于PL/SQL开发的入门级指导材料,面向希望学习使用PL/SQL进行数据库程序单元开发的用户。文档很可能是Oracle公司内部或其授权的培训机构用于教学目的的官方材料。 ...
PL/SQL是Oracle公司开发的一种过程化语言,全称为Procedural Language/Structured Query Language,它是SQL的一个扩展,专门用于处理Oracle数据库系统。这个“PL/SQL工具”显然是一个用于辅助管理和操作Oracle数据库...
Oracle 10g PL/SQL 是Oracle数据库系统中用于创建和管理存储过程、函数、触发器等数据库对象的编程语言。本教程旨在为初学者提供一个全面的学习平台,同时也为经验丰富的开发者提供参考资料。PL/SQL是Oracle特有的...
### PL/SQL 开发手册:Oracle 初学者的全面指南 #### 一、PL/SQL:Oracle 的核心编程语言 PL/SQL(Procedural Language for SQL)是Oracle数据库的标准编程语言,它结合了SQL的强大数据操作能力和过程化语言的控制...
PL/SQL Developer是一款专为PL/SQL编程和Oracle数据库管理设计的强大开发工具。这款软件提供了全面的功能,使得数据库开发者和管理员能够高效地进行各种数据库操作,包括编写、调试、执行和管理PL/SQL代码,以及...
在本文中,我们将深入探讨PL/SQL Developer的功能、特性以及它在Oracle数据库开发中的作用。 PL/SQL(Procedural Language/Structured Query Language)是Oracle数据库系统中用于数据库编程的一种扩展SQL语言。它...
Oracle PL/SQL是一种强大的编程语言,它结合了SQL的数据处理能力与PL的程序设计特性,是Oracle数据库系统中用于创建存储过程、函数、触发器和包的主要工具。在这个"Oracle PL/SQL实战(待续)"的主题中,我们将深入...
PL/SQL是Oracle数据库系统中的一个关键组件,全称为Procedural Language/Structured Query Language,是一种结合了SQL和过程编程语言的工具,主要用于编写数据库应用程序。64位的PL/SQL开发者工具对于那些处理大数据...
### Oracle 9i PL/SQL程序设计笔记精要 ...掌握PL/SQL的不同块类型及其使用方法对于开发高效、可靠的数据库应用程序至关重要。此外,熟悉存储过程和触发器的创建与使用,将有助于提升应用程序的性能和数据安全性。
PL/SQL VCS插件是为开发者提供的一种增强工具,它与PL/SQL Developer整合,目的是为了更好地管理和控制Oracle数据库中的SQL脚本和存储过程的版本。这个安装包结合了Version Control System (VCS)的功能,如Visual ...
ORACLE PL/SQL是从入门到精通的专业知识,涵盖了数据库开发与管理的多个方面,包括触发器、过程、函数、软件包、异常处理、游标、循环、分支、变量使用、数据库安装等关键知识点。 触发器是数据库中用来保证数据...
PL/SQL Developer是一款由Allround Automations公司开发的专门用于Oracle数据库管理的集成开发环境(IDE)。这款软件为Oracle数据库管理员、开发人员和测试人员提供了便捷的SQL和PL/SQL编写、调试和执行功能。而“pl...
PL/SQL Developer是一款高效、便捷的Oracle数据库管理工具,尤其适合DBA和开发人员使用。免安装的绿色版PL/SQL Developer使得用户无需经历复杂的安装过程,只需解压即可使用,大大简化了软件部署,方便在不同的...
#### 四、PL/SQL中的SQL - **SQL语句的执行**:介绍如何在PL/SQL代码中嵌入SQL语句,包括查询、插入、更新和删除操作。 - **动态SQL**:探讨如何构造和执行动态SQL语句,这对于需要根据运行时条件生成SQL的情况非常...
使用PL/SQL Developer中文指南,开发者可以学习如何有效地使用该工具,掌握数据库开发的常用技巧,提升工作效率。 总的来说,PL/SQL Developer中文指南是一份宝贵的参考资料,无论对于初学者还是经验丰富的开发者...
《Oracle PL/SQL专家指南-高级PL/SQL解决方案的设计与开发》是一本深入探讨Oracle数据库中的PL/SQL编程的专业书籍。PL/SQL是Oracle数据库特有的编程语言,它结合了SQL的查询能力与过程式编程语言的功能,使得数据库...
PL/SQL是Oracle数据库系统中的一个关键组成部分,它是一种结合了SQL语言与过程编程的语言,专为数据库管理和应用程序开发设计。PL/SQL全称为“Procedural Language/Structured Query Language”,它提供了丰富的控制...
这篇博客主要探讨了PL/SQL的基础知识,包括其语法特性、使用场景以及在数据库管理中的重要性。 首先,PL/SQL是一种过程化语言,它允许用户定义变量、控制流程(如循环、条件语句)、处理异常,并且可以嵌入SQL查询...