Update优化小结
hit12345 | 23 七月, 2005 15:43
一,基础知识
1, 关联子查询和非关联子查询
在非关联子查询中,内部查询只执行一次并返回它的值给外部查询,然后外部查询在它的处理中使用内部查询返回给它的值。而在关联子查询中,对于外部查询返回的每一行数据,内部查询都要执行一次。另外,在关联子查询中是信息流是双向的。外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。
如:
SELECT o1.CustomerID, o1.OrderID, o1.OrderDate
FROM Orders o1
WHERE o1.OrderDate = (SELECT Max(OrderDate)
FROM Orders o2
WHERE o2.CustomerID = o1.CustomerID)
是一个关联子查询
SELECT o1.CustomerID, o1.OrderID, o1.OrderDate
FROM Orders o1
WHERE o1.OrderDate IN
(SELECT TOP 2 o2.OrderDate
FROM Orders o2
WHERE o2.CustomerID = o1.CustomerID)
ORDER BY CustomerID
是一个非关联子查询
2, 提示(HINT)
一般在优化时,无论采用基于规则的或是基于代价的方法,由Oracle系统的优化器来决定语句的执行路径。这样的选择的路径不要见得是最好的。所以,Oracle提供了一种方法叫提示的方法。它可以让编程人员按照自己的要求来选择执行路径,即提示优化器该按照什么样的执行规则来执行当前的语句。这样可以在性能上比起Oracle优化自主决定要好些。
通常情况下,编程人员可以利用提示来进行优化决策。通过运用提示可以对下面内容进行指定:
l SQL语句的优化方法;
l 对于某条SQL语句,基于开销优化程序的目标;
l SQL语句访问的访问路径;
l 连接语句的连接次序;
l 连接语句中的连接操作。
如果希望优化器按照编程人员的要求执行,则要在语句中给出提示。提示的有效范围有限制,即有提示的语句块才能按照提示要求执行。下面语句可以指定提示:
l 简单的SELECT ,UPDATE ,DELETE 语句;
l 复合的主语句或子查询语句;
l 组成查询(UNION)的一部分。
提示的指定有原来的注释语句在加“+”构成。语法如下:
[ SELECT | DELETE|UPDATE ] /*+ [hint | text ] */
或
[ SELECT | DELETE|UPDATE ] --+ [hint | text ]
注意在“/*”后不要空就直接加“+”,同样 “--+”也是连着写。
警告:如果该提示语句书写不正确,则Oracle就忽略掉该语句。
常见的提示有:
Ordered 强制按照from子句中指定的表的顺序进行连接
Use_NL 强制指定两个表间的连接方式为嵌套循环(Nested Loops)
Use_Hash 强制指定两个表间的连接方式为哈希连接(Hash Join)
Use_Merge 强制指定两个表间的连接方式为合并排序连接(Merge Join)
Push_Subq 让非关联子查询提前执行
Index 强制使用某个索引
3, 执行计划
在PL/SQL Developer的SQL WINDOWS中用鼠标或键盘选中SQL语句,然后按F5,就会出现执行计划解析的界面:
4, Update的特点
Update的系统内部执行情况可以参照附文:对update事务的内部分析.doc
使用Update的基本要点就是,
1) 尽量使用更新表上的索引,减少不必要的更新
2) 更新的数据来源花费时间尽可能短,如果无法做到就把更新内容插入到中间表中,然后给中间表建上索引,再来更新
3) 如果更新的是主键,建议删除再插入。
5, 示例用表
后面的阐述将围绕以下两张表展开:
Create table tab1 (workdate varchar2(8), cino varchar2(15), val1 number, val2 number);
Create table tab2 (workdate varchar2(8), cino varchar2(15), val1 number, val2 number);
Create table tab3 (workdate varchar2(8), cino varchar2(15), val1 number, val2 number);
Create table tab4 (workdate varchar2(8), cino varchar2(15), val1 number, val2 number);workdate, cino为两张表的关键字,默认情况没有建主键索引。
二,Update两种情况
用Update更新某个表,无外乎是两种情况:根据关联子查询,更新字段;通过非关联子查询,限定更新范围。如果还有第三种情况,那就是前两种情况的叠加。
1, 根据关联子查询,更新字段
Update tab1 t
Set (val1, val2) = (select val1, val2
from tab2
where workdate = t.workdate
and cino = t.cino);
通过tab2来更新tab1的相应字段。执行SQL语句时,系统会从tab1中一行一行读记录,然后再通过关联子查询,找到相应的字段来更新。关联子查询能否通过tab1的条件快速的查找到对应记录,是优化能否实现的必要条件。所以一般都要求在tab2上建有Unique或者排重性较高的Normal索引。执行所用时间大概为(查询tab1中一条记录所用的时间 + 在tab2中查询一条记录所用的时间)* tab1中的记录条数。
如果子查询条件比较复杂,如以下语句:
Update tab1 t
Set (val1, val2) = (select val1, val2
from tab2 tt
where exists (select 1
from tab3
where workdate = tt.workdate
and cino = tt.cino)
and workdate = t.workdate
and cino = t.cino);这时更新tab1中的每条记录花费在子查询上的时间将成倍增加,如果tab1中的记录数较多,这种更新语句几乎是不可完成。
解决方式是,把子查询提取出来,做到中间表中,然后给中间表建上索引,用中间表来代替子查询,这样速度就能大大提高:
Insert into tab4
select workdate, cino, val1, val2
from tab2 tt
where exists (select 1
from tab3
where workdate = tt.workdate
and cino = tt.cino);
create index tab4_ind01 on tab4(workdate, cino);
Update tab1 t
Set (val1, val2) = (select val1, val2
from tab4 tt
where workdate = t.workdate
and cino = t.cino);
2, 通过非关联子查询,限定更新范围
Update tab1 t
set val1 = 1
where (workdate, cino) in (select workdate, cino from tab2)
根据tab2提供的数据范围,来更新tab1中的相应记录的val1字段。
在这种情况下,系统默认执行方式往往是先执行select workdate, cino from tab2子查询,在系统中形成系统视图,然后在tab1中选取一条记录,查询系统视图中是否存在相应的workdate, cino组合,如果存在,则更新tab1,如果不存在,则选取下一条记录。这种方式的查询时间大致等于:子查询查询时间 + (在tab1中选取一条记录的时间 + 在系统视图中全表扫描寻找一条记录时间)* tab1的记录条数。其中“在系统视图中全表扫描寻找一条记录时间”会根据tab2的大小而有所不同。若tab2记录数较小,系统可以直接把表读到系统区中;若tab2记录数多,系统无法形成系统视图,这时会每一次更新动作,就把子查询做一次,速度会非常的慢。
针对这种情况的优化有两种
1) 在tab1上的workdate, cino字段上加入索引,同时增加提示。
修改以后的SQL语句如下:
Update /*+ordered use_nl(sys, t)*/ tab1 t
set val1 = 1
where (workdate, cino) in (select workdate, cino from tab2)
其中sys表示系统视图。如果不加入ordered提示,系统将会默认以tab1表作为驱动表,这时就要对tab1作全表扫描。加入提示后,使用系统视图,即select workdate, cino from tab2,作为驱动表,在正常情况下,速度能提高很多。
2) 在tab2表上的workdate, cino字段加入索引,同时改写SQL语句:
Update tab1 t
set val1 = 1
where exists (select 1
from tab2
where workdate = t.workdate
and cino = t.cino)
三,索引问题
update索引的使用比较特殊,有时看起来能用全索引,但实际上却只用到一部分,所以建议把复合索引的各字段写在一起。
例如:
Update /*+ordered use_nl(sys, t)*/ tab1 t
set val1 = 1
where cino in (select cino from tab2)
and workdate = '200506'
这条SQL语句是不能完全用到tab1上的复合索引workdate + cino的。能用到的只是workdate=’200506’的约束。
如果写成这样,就没问题:
Update /*+ordered use_nl(sys, t)*/ tab1 t
set val1 = 1
where (workdate, cino) in (select workdate, cino from tab2)
分享到:
相关推荐
15. **索引策略**:不是所有字段都需要索引,过多的索引会降低INSERT和UPDATE操作的性能,需要根据业务需求和数据更新频率权衡。 优化SQL查询不仅关乎技术,更是一种平衡艺术,需要结合具体数据库架构、数据分布...
尽量减少`SELECT`、`INSERT`和`UPDATE`操作,尤其是频繁的`UPDATE`,并且确保使用索引来加速查询。 4. **使用内置函数**: PHP内建的函数通常比自定义函数执行更快,因此应优先使用内置函数。 5. **循环内不声明...
- Background Intelligent Transfer Service:在后台传输文件,如Windows Update。 - BranchCache:提高网络内容的获取速度,尤其是局域网内的文件共享。 - Bluetooth Support Service:支持蓝牙设备的连接和配对...
ExecuteNonQuery用于执行数据更新操作(如INSERT、UPDATE、DELETE),它不需要返回结果集,因此性能开销较小。该命令执行后,会返回受影响的行数。 ExecuteScalar用于返回结果集中的单个值,比如查询某个ID或计数等...
#### 四、小结 通过上述介绍,我们可以了解到Linux系统启动的基本流程和运行级别的概念,同时掌握了如何使用`update-rc.d`命令在Ubuntu系统中配置开机自启动服务的方法。这对于系统管理员来说是非常实用的知识点,...
1.6 小结 14 第2章 系统性能分析 15 2.1 性能监视器工具 15 2.2 动态管理视图 17 2.3 硬件资源瓶颈 18 2.3.1 识别瓶颈 18 2.3.2 瓶颈解决方案 19 2.4 内存瓶颈分析 19 2.4.1 SQL Server内存管理 20 2.4.2 ...
这里,我们将围绕“WinXP技巧小结”这个主题,详细讲解一些重要的知识点。 1. 快速启动程序:利用启动菜单的快捷方式,用户可以直接在开始菜单的“所有程序”下创建常用软件的快捷方式,方便快速启动。同时,还可以...
【数据库知识小结】 在IT领域,数据库是一个至关重要的组成部分,尤其在数据管理和分析中扮演着核心角色。这里我们将深入探讨Oracle数据库以及一些常见的数据库理论和优化策略。 首先,让我们来了解一下数据库三...
1.4 小结 19 第2章 锁和阻塞 20 2.1 关于锁 20 2.2 锁和阻塞 22 2.3 引起阻塞的其他情况 30 2.3.1 select for update 30 2.3.2 外键和索引 36 第3章 latch和等待 44 3.1 共享池中的latch争用 45 .3.2 数据缓冲池...
这篇博客"Oracle使用小结"可能涵盖了数据库的安装、配置、查询优化、性能监控以及日常维护等多个方面。由于没有提供具体的博客内容,我会根据一般Oracle使用中的常见知识点进行详细阐述。 1. **Oracle安装与配置**...
### FORALL 用法小结:提升Oracle性能的关键 #### 引言 在Oracle数据库的开发与维护过程中,性能优化始终是关注的重点之一。其中,`FORALL`语句作为Oracle PL/SQL的一个强大特性,提供了批量绑定和批量收集的能力...
### TensorFlow语法小结 在深度学习领域中,TensorFlow是一个非常强大的开源库,它由Google Brain团队开发并维护。此工具被广泛应用于机器学习、神经网络等场景中。以下是对给定文件中的关键知识点进行详细解释。 ...
### PL/SQL Developer 使用技巧小结 #### 一、PL/SQL Developer 记住登录密码功能 在使用 PL/SQL Developer 进行数据库操作时,频繁地输入用户名和密码可能会带来不便。为了提高工作效率,我们可以设置让 PL/SQL ...
优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过); 4.尽可能的使用PHP内部函数(但是我却为了找个PHP里面不存在的函数,浪费了本可以写出一个自定义函数的时间,经验问题...
【SQL语法小结】 SQL(Structured Query Language)是用于管理和处理关系数据库的标准语言。它涵盖了数据查询、数据更新、数据插入以及数据删除等操作。以下是对SQL语法的一些关键点的详细说明: **2. ASP与SQL...
`db2 get dbm cfg`和`db2 get db cfg for [db name]`用于查看数据库管理配置,`db2 update dbm cfg`或`db2 update db cfg for [db name]`则用于更新配置,例如调整日志空间大小,以优化数据库性能。 以上命令只是...
1.4 小结 19 第2章 锁和阻塞 20 2.1 关于锁 20 2.2 锁和阻塞 22 2.3 引起阻塞的其他情况 30 2.3.1 select for update 30 2.3.2 外键和索引 36 第3章 latch和等待 44 3.1 共享池中的latch争用 45 .3.2 数据缓冲池...
**ES6.6.2 使用小结 - Java操作Elasticsearch基本测试** 在现代Web开发中,Elasticsearch(简称ES)作为一个强大的分布式搜索引擎,被广泛应用于数据分析、日志存储和全文检索等领域。本章我们将重点总结ES6.6.2...
1.6 小结 14 第2章 系统性能分析 15 2.1 性能监视器工具 15 2.2 动态管理视图 17 2.3 硬件资源瓶颈 18 2.3.1 识别瓶颈 18 2.3.2 瓶颈解决方案 19 2.4 内存瓶颈分析 19 2.4.1 SQL Server内存管理 20 2.4.2 ...