update的优化

在olap中,往往能看到性能很差的语句是update语句,跑半天都跑不过去,虽然语句可以千变万化,但是优化起来还是有规可循的。

--测试表:
drop table t1;
drop table t2;
create table t1 as select * from dba_objects;
create table t2 as select * from dba_objects;

--原始update语句
update t1 set t1.owner=(select t2.owner from t2 where t2.object_id=t1.object_id);

--683s

rollback;

执行计划如下:
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | UPDATE STATEMENT   |      | 69746 |  2043K|   150   (1)| 00:00:03 |
|   1 |  UPDATE            | T1   |       |       |            |          |
|   2 |   TABLE ACCESS FULL| T1   | 69746 |  2043K|   150   (1)| 00:00:03 |
|*  3 |   TABLE ACCESS FULL| T2   |   546 | 16380 |   150   (1)| 00:00:03 |
---------------------------------------------------------------------------

两个小表居然花了10多分钟,至于为什么这么慢,我就不说了,要研究的话可以看下语句真实的执行计划,请看《如何获取执行计划》这篇文章,我只说一下优化的方法。

--1建立组合索引
create index idx on t2(object_id,owner);
update t1 set t1.owner=(select t2.owner from t2 where t2.object_id=t1.object_id);

--0.7s

rollback;
因为t2只用到了两个字段的数据,object_id和owner,考虑将起建立组合索引,扫描的时候只需要扫描索引中的数据即可
只能用object_id,owner的顺序才能让索引走range scan提高效率,owner,object_id的顺序是错的。
--2plsql分批update
declare
v_count number;
cursor c is
select t1.rowid row_id,t2.object_id,t2.owner from t1,t2 where t1.object_id=t2.object_id;
begin
  v_count:=0;
  for x in c loop
    update t1 set t1.owner=x.owner where rowid=x.row_id;
    v_count:=v_count+1;
    if (v_count>=1000) then
      commit;
      v_count:=0;
    end if;
  end loop;
  commit;
end;

--1.9s
通过rowid定位update的数据,避免每次update都走全表扫描。
--3merger into优化(undo较多,怕死事务恢复)
merge into  t1
using  t2
on (t1.object_id=t2.object_id)
when matched then
  update set t1.owner=t2.owner;

--0.84s

  总结:
直接update大表是最垃圾的写法。
方法1:当表较小时,效率较高。可以这样用。当表大时,频繁扫描索引,会产生热点块,会产生锁等待:cbc latch。不推荐。
方法2:当表大时,推荐用这种方法,分批提交,避免大事务。不然大事务一直不提交占用回滚段,容易报回滚段不足的错。这也是为什么有时候跑数跑不过,有时候又没问题的根本原因。不是oracle的问题,是语句的问题。
方法3:如果你用set autotrace on的方法测试,你会发现merge产生的undo是非常多的。一旦断电或者其他原因造成数据库down机,那么就完了。。。数据库为了保证数据的一致性,启动之后要读undo进行恢复,读undo是单块读,非常慢,如果多块读参数为16,你merge了1个小时还没完成,突然down机了,那么恢复起来就要16个小时才能恢复完,数据库16个小时不能工作那就坑爹了。。。

时间: 2024-10-05 17:43:08

update的优化的相关文章

Oracle的update语句优化研究

最近研究sql优化,以下文章转自互联网: 1.     语法 单表:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 如:update t_join_situation set join_state='1'whereyear='2011' 更新年度为“2011”的数据的join_state字段为“1”.如果更新的字段加了索引,更新时会重建索引,更新效率会慢. 多表关联,并把一个表的字段值更新到另一个表中的字段去: update 表a set a.字段1 = (sele

UPDATE sql 优化

一个网友说他的存储过程中有一段update sql,运行了15分钟还没出结果,需要优化一下 他把sql发给我 UPDATE TB_RESULT R SET R.VOTE_COUNT=NVL(( SELECT TEMP_.VOTE_COUNT FROM ( SELECT RESULT_ID, COUNT(RV_ID) AS VOTE_COUNT FROM TB_RESULT_VOTE GROUP BY RESULT_ID ) TEMP_ WHERE TEMP_.RESULT_ID = R.RESU

[转]Oracle的update语句优化研究

原文地址:http://blog.csdn.net/u011721927/article/details/39228001 一.         update语句的语法与原理 1.     语法 单表:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 如:update t_join_situation set join_state='1'whereyear='2011' 更新年度为"2011"的数据的join_state字段为"1".如果

MySql数据库3【优化2】sql语句的优化

1.SELECT语句优化 1).利用LIMIT 1取得唯一行[控制结果集的行数] 有时,当你要查询一张表是,你知道自己只需要看一行.你可能会去的一条十分独特的记录,或者只是刚好检查了任何存在的记录数,他们都满足了你的WHERE子句.在这种情况下,增加一个LIMIT 1会令你的查询更加有效.这样数据库引擎发现只有1后将停止扫描,而不是去扫描整个表或索引. 2).不要使用BY RAND()命令 这是一个令很多新手程序员会掉进去的陷阱.你可能不知不觉中制造了一个可怕的平静.这个陷阱在你是用BY RAN

浅谈Vue项目优化

前几天看到大家说 vue 项目越大越难优化,带来很多痛苦,这是避免不了的,问题终究要解决,框架的性能是没有问题的,各大测试网站都有相关数据.下面进入正题 转自https://blog.csdn.net/qq_33834489/article/details/79144762 基础优化 所谓的基础优化是任何 web 项目都要做的,并且是问题的根源.HTML,CSS,JS 是第一步要优化的点 分别对应到 .vue 文件内的,<template>,<style>,<script&g

250. Count Univalue Subtrees

题目: Given a binary tree, count the number of uni-value subtrees. A Uni-value subtree means all nodes of the subtree have the same value. For example:Given binary tree, 5 / 1 5 / \ 5 5 5 return 4. 链接: http://leetcode.com/problems/count-univalue-subtre

Cocos2d-x v3.9发布

近日, Cocos引擎完成重大更新:发布了Cocos 2d-x v3.9版本.据悉,Cocos 2d-x v3.9版本补全了3D功能,大大提升了画面表现力:同时在更稳定的2D功能基础上,强化了2D功能的易用性,让代码更为优雅.该版本进一步完善并整合了历史零碎功能,为开发者创造更为简单.快捷的开发环境. Cocos 3D功能日益完善 (Cocos引擎打造的拖尾效果) 此次Cocos 2d-x v3.9新增3D MotionStreak功能,支持拖尾效果. 在游戏的实现过程中,开发者有时会需要在某个

JavaScript 高级程序设计之最佳实践

一.可维护性:可理解性.直观性.可适应性.可扩展性.可调试性 代码约定: 可读性 格式化:建议缩进大小为4个空格 注释:函数和方法.大段代码.复杂的算法.hack 变量和函数命名 变量名为名词 函数名为动词开始 变量和函数使用合符逻辑的名字,不要担心长度. 变量类型透明:表示变量类型的三种方式 初始化: var found = false; //布尔型 使用匈牙利标记法来指定变量类型:o代表对象,s代表字符串,i代表整数,f代表浮点数,b代表布尔型 使用类型注释: var found /*:Bo

JIRA&amp;Confluence

JIRA是atlassian开发的一套项目与事务跟踪工具,confluence是一个企业知识管理与协同软件,可以构建企业wiki.软件运行基于Java环境. JDK 安装 下载jdk-7u71-linux-x64.tar.gz 解压到/usr/java下 tar zxf jdk-7u71-linux-x64.tar.gz -C /usr/java/ 添加变量到/etc/profile export JAVA_HOME=/usr/java/jdk1.7.0_71 export PATH=$JAVA