`
izuoyan
  • 浏览: 8949396 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

insert之后update和insert之中left join效率测试

 
阅读更多

前天有同事在QQ上问了我个问题:
问一下,insert之后update和insert语句中使用left join哪个效率高一些?每个update 差不多4个字段这样。
我脑海里第1刻闪过的答案是:后者效率更高。
依据如下:
1、从生成redo和undo来考虑
2、直观的执行时间考虑
3、减少访问表的次数
事后把这个问题拿到,网络讨论的意见基本和我一致。
那么下面我们就对此进行简单的测试,验证下理论依据。
测试很简单,创建一个测试表(准备插入的数据是dba_objects的记录),记录2个方案的redo、undo生成量和执行时间。
Last login: Sat Feb 12 10:06:58 2011 from 192.168.112.1
[oracle@gtlions ~]$ sqlplus /nolog

SQL*Plus: Release 11.2.0.1.0 Production on 星期六 2月 12 10:12:22 2011

Copyright (c) 1982, 2009, Oracle. All rights reserved.

idle> conn store/store
已连接。
store(at)TEST> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

store(at)TEST> create table test_insert_update as select * from dba_objects where 1=2;

表已创建。

store(at)TEST> Create Global Temporary Table tempstat(Type varchar2(10),Sid Number,statname Varchar2(64),Value Number) On Commit Preserve Rows;

表已创建。
好勒,基本测试环境准备完毕,下面进行测试。
1、测试方案1,insert之后再update4个字段

store(at)TEST> Alter System Flush buffer_cache;

系统已更改。

store(at)TEST> Alter System Flush shared_pool;

系统已更改。
store(at)TEST> declare
2 begin
3 Insert Into tempstat(type,Sid,statname,value) Select 'begin',a.sid,b.NAME,a.VALUE From v$mystat a,v$statname b Where a.STATISTIC#=b.STATISTIC# And b.name In ('DB time','redo size','undo change vector size','recursive calls');
4 Insert Into test_insert_update Select * From Dba_Objects;
5 Update test_insert_update a Set (a.owner,a.object_name,a.object_type,a.status)=(Select 'test' owner,'test' object_name,'test' object_type,'test' status from dual);
6 Insert Into tempstat(type,Sid,statname,value) Select 'end',a.sid,b.NAME,a.VALUE From v$mystat a,v$statname b Where a.STATISTIC#=b.STATISTIC# And b.name In ('DB time','redo size','undo change vector size','recursive calls');
7 commit;
8 end;
9 /

PL/SQL 过程已成功完成。

store(at)TEST> column statname format a20;
store(at)TEST> select a.sid,a.statname,a.type,a.value,b.type,b.value from tempstat a, tempstat b where a.type='begin' and b.type='end' and a.statname=b.statname;

SID STATNAME TYPE VALUE TYPE VALUE
---------- -------------------- ---------- ---------- ---------- ----------
101 recursive calls begin 21208 end 24944
101 DB time begin 301 end 301
101 redo size begin 38324 end 32473384
101 undo change vector s begin 11048 end 11062672
ize

2、测试方案2,insert带上left join
为了干净测试,创建2个测试表格。
Last login: Sat Feb 12 10:12:19 2011 from 192.168.112.1
[oracle@gtlions ~]$ sqlplus /nolog

SQL*Plus: Release 11.2.0.1.0 Production on 星期六 2月 12 10:19:40 2011

Copyright (c) 1982, 2009, Oracle. All rights reserved.

idle> conn store/store
已连接。
store(at)TEST> drop table test_insert_update;

表已删除。

store(at)TEST> drop table tempstat;

表已删除。
store(at)TEST> create table test_insert_update as select * from dba_objects where 1=2;

表已创建。

store(at)TEST> Create Global Temporary Table tempstat(Type varchar2(10),Sid Number,statname Varchar2(64),Value Number) On Commit Preserve Rows;

表已创建。

store(at)TEST> Alter System Flush buffer_cache;

系统已更改。

store(at)TEST> Alter System Flush shared_pool;

系统已更改。

store(at)TEST> declare
2 begin
3 Insert Into tempstat(type,Sid,statname,value) Select 'begin',a.sid,b.NAME,a.VALUE From v$mystat a,v$statname b Where a.STATISTIC#=b.STATISTIC# And b.name In ('DB time','redo size','undo change vector size','recursive calls');
Insert Into test_insert_update Select b.owner,b.object_name,a.SUBOBJECT_NAME,a.OBJECT_ID,a.DATA_OBJECT_ID,b.object_type,a.CREATED,a.LAST_DDL_TIME,a.TIMESTAMP,b.status,a.TEMPORARY,a.GENERATED,a.SECONDARY,a.namespace,a.EDITION_NAME From Dba_Objects a
5 left join (Select 'test' owner,'test' object_name,'test' object_type,'test' status from dual) b on 1=1;
6 Insert Into tempstat(type,Sid,statname,value) Select 'end',a.sid,b.NAME,a.VALUE From v$mystat a,v$statname b Where a.STATISTIC#=b.STATISTIC# And b.name In ('DB time','redo size','undo change vector size','recursive calls');
7 commit;
8 end;
9 /

PL/SQL 过程已成功完成。

store(at)TEST> column statname format a20;
store(at)TEST> select a.sid,a.statname,a.type,a.value,b.type,b.value from tempstat a, tempstat b where a.type='begin' and b.type='end' and a.statname=b.statname;

SID STATNAME TYPE VALUE TYPE VALUE
---------- -------------------- ---------- ---------- ---------- ----------
101 recursive calls begin 54213 end 57750
101 DB time begin 420 end 420
101 redo size begin 48688 end 6541740
101 undo change vector s begin 14676 end 268776
ize


store(at)TEST> Select 6541740-48688 As "测试2redo",32473384-38324 As "测试1redo",268776-14676 As "测试2undo",11062672-11048 As "测试1undo"From dual;

测试2redo 测试1redo 测试2undo 测试1undo
---------- ---------- ---------- ----------
6493052 32435060 254100 11051624
小结
比较这2次测试,数据是最有力的证据。我们可以看到测试结果正如我们预料的那样,在语句当中尽量减少表格的访问次数,能在一起执行的语句不要人为分开来。
自己有点疑问的是DB time似乎我理解错误了:为什么这个值在两次测试都没有变化。
-The End-

分享到:
评论

相关推荐

    SQL 语法 SQL 总结 SQL教程

    SQL Left Join SQL Right Join SQL Full Join SQL Union SQL Select Into SQL Create DB SQL Create Table SQL Constraints SQL Not Null SQL Unique SQL Primary Key SQL Foreign Key SQL Check SQL ...

    SQL语句生成及分析器

    内连接(inner join)和外连接(left join/right join/full join) 排序(Order By) 条件(Where) 分组(Group By) 分组条件(Having) 计算字段 SQL查询表 SQL查询子句 丰富的函数 表别名 字段别名 联合(Union...

    开发人员的 MySQL 教程.zip

    本节将帮助您熟悉基本的 MySQL 知识,包括使用各种 SQL 语句(如INSERT,DELETE,UPDATE和SELECT)来管理 MySQL 数据库和操作数据。还将了解高级数据查询技术,包括INNER JOIN,LEFT JOIN,子查询,UNION等。 参考阅读...

    Sql 语句详解

    18. SQL LEFT JOIN 关键字 23 19. SQL RIGHT JOIN 关键字 24 20. SQL UNION 和 UNION ALL 操作符 26 21. SQL SELECT INTO 语句 28 22. SQL CREATE DATABASE 语句 29 23. SQL CREATE TABLE 语句 29 24. SQL 约束 ...

    通过参数生成MYSQL语句的PHP类 v1.4.rar

    下面这个类可以通过具有参数的数组来构建MySQL查询语句,通过指定的表和字段参数创建SELECT ,INSERT , UPDATE和DELETE语句,创建SQL语句的WHERE条件,像LIKE的查询语句,使用LEFT JOIN和ORDER 语句。

    通过参数生成MYSQL语句的PHP类 v1.4

    下面这个类可以通过具有参数的数组来构建MySQL查询语句,通过指定的表和字段参数创建SELECT ,INSERT , UPDATE和DELETE语句,创建SQL语句的WHERE条件,像LIKE的查询语句,使用LEFT JOIN和ORDER 语句。

    我的 ORM 框架

    使用运算符重载,实现 ORM 框架里的 INSERT、UPDATE、DELETE 和 SELECT 语句动态生成。SELECT 语句支持 INNER JOIN、LEFT OUTER JOIN 和RIGHT OUTER JOIN 多表联合查询,但不支持同一表的联合查询。 代码中只实现了 ...

    SQL语法大全

    sql="insert into 目标数据表 select * from 源数据表" (把源数据表的记录添加到目标数据表) (5) 数据记录统计函数: AVG(字段名) 得出一个表格栏平均值 COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据...

    MySQL命令大全

     此操作使testuser能够在每一个test数据库中的表执行SELECT,INSERT和DELETE以及UPDATE查询操作。现在我们结束操作并退出MySQL客户程序:  mysql> exit  Bye9! 1:使用SHOW语句找出在服务器上当前存在什么...

    MYSQL常用命令大全

     此操作使testuser能够在每一个test数据库中的表执行SELECT,INSERT和DELETE以及UPDATE查询操作。现在我们结束操作并退出MySQL客户程序:  mysql> exit  Bye9! 1:使用SHOW语句找出在服务器上当前存在什么...

    基于【MySQL】的【SQL核心语法】实战演练(一)

    文章目录说明必知必会建表多行插入LIMIT语句创建新表LIKE操作符IN操作符BETWEEN操作符AS操作符INSERT INTO SELECT语句JOIN语句INNER JOINLEFT JOINRIGHT JOINFULL JOINUNION操作符约束相关CREATE INDEX语句完美退出...

    SQL语句生成及分析器(中文绿色)

    3.7.1 SQL 92 标准:Inner Join、Left Join、Right Join、Full Join, 3.7.2 特殊语法:*=、=*、*=*(MS_SQL,Sybase),(+)(Oracle) 3.8 联合 (Union [All],Minus,Intersect) 3.9 字段别名,数据表别名 ...

    经典全面的SQL语句大全

    select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....  12、说明:日程安排提前五分钟提醒 SQL: select * from 日程安排 where datediff('minute',f...

    阿里巴巴大数据之路——数据技术篇.pdf

    实例参考如下: SQL的Join语法有很多, inner join(等值连接) 只返回两个表中联结字段相等的⾏, left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录, right join(右联接) 返回包括右表中的...

    SQL sever 实训

    --使用IF UPDATE(column)尽可能优化上题的触发器,以提高系统效率 ALTER TRIGGER UPDATE_ProNo_Stocks_TRIGGER ON Product FOR UPDATE AS IF UPDATE (ProNo) PRINT '已更新' GO --单元十三 游标 --创建存储过程...

    ecshop架构改写

    表名:“user” 或者 array(“left_join”=>array()) 典型例子(复杂写法有联表查询): echo DbHelper::selectSql( array( "left_join"=>array( "a"=>"museum_decorate_order", "b"=>"users","c"=>"cesi3biao",...

    sql语句生成与分析器.rar

    3.7.1 SQL 92 标准:Inner Join、Left Join、Right Join、Full Join, 3.7.2 特殊语法:*=、=*、*=*(MS_SQL,Sybase),(+)(Oracle) 3.8 联合 (Union [All],Minus,Intersect) 3.9 字段别名,数据表别名 ...

    PHP实现的通过参数生成MYSQL语句类完整实例

    这个类可以通过指定的表和字段参数创建SELECT ,INSERT , UPDATE 和 DELETE 语句。 这个类可以创建SQL语句的WHERE条件,像LIKE的查询语句,使用LEFT JOIN和ORDER 语句 <?php /* *******************************...

    LINQ_to_SQL语法及实例大全

    3.左外部联接(Left Outer Join): 17 4.投影的Let赋值(Projected let assignment): 17 5.组合键(Composite Key): 18 6.可为null/不可为null的键关系 (Nullable/Nonnullable Key Relationship): 19 LINQ to SQL...

    Mysql DBA 20天速成教程

    基本sql 语法:select/insert/update/delete,掌握最基本的语法即可,什么inner join,left join的了解就行 mysql的应用场景大多都是高并发访问/业务逻辑简单,join/子查询/视图/触发器 基本上不用10.sql 聚集查询:...

Global site tag (gtag.js) - Google Analytics