- 浏览: 1499916 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
1 深入理解嵌套循环执行计划
为什么要引入散列连接呢?假设两张表t1(c1 int,c2 int),t2(d1 int,d2 int),查询语句为select c1,d1 from t1 inner join t2 on c1=d1。如果数据库没有实现散列连接、合并连接的话,只能选择使用嵌套循环。从上篇文章中我们可以得到,对于t1的每一条记录,都需要遍历t2的每一条记录。因此,当t1的记录数数为m,t2的记录数为n,那么该查询语句访问的记录次数为m*n。当m=10000、n=10000时,那么m*n=100000000(1亿)。这是比较夸张的浪费时间。如果m是100万,n是100万,那么m*n就是1万亿次,读一万亿次记录,这是不能忍受的。
这里需要提到的一点是:我们不以读取记录的多少作为评价标准,在实际代价评估中,采用数据页(也可称为数据块,I/O的基本单位)。但是两者之间又是有联系的,假设每个页存放100个数据,那么t1的数据页为100页(10000/100),t2的数据页为100页,那么对于t1中的每一条记录,需要遍历t2的100页,加上该记录在t1中也属于一个数据页。因此,对于t1中的每一个记录,需要访问101个数据页。那么该查询的I/O量为:10000*(100+1)=1010000页。如果考虑到数据页的缓冲,情况会更加复杂。代价评估是个很复杂的课题,可能需要单独写个系列来阐述数据库查询优化系统的代价评估模型。这里我们不考虑数据页缓冲,也就相当于假设数据库缓冲区的大小仅仅为1个页。
好了,继续前面的话题。
如果t1(c1)上建立有唯一索引iut1c1,那么可以将t2作为外表,对于t2的每一条记录,使用d1的值去命中索引iut1c1对应的B树。假设该B树的高度为3层,那么对于t2的每一条记录,需要访问t1表索引iut1c1中三个页(B树的高度),加上本身在t2中属于一个页。所以,在这种情况下,查询代价为:10000*(3+1)=40000页。
我们来对比一下,没有索引与有索引,两者之间的代价对比约等于25:1(比值1010000:40000)。也可以这么认为,假设没有索引的时候执行需要25s,那么有索引的情况下只需要1s。
这里我们把话题再延展下,如果m,n都为1000000,占用的块都为10000页(1000000/100)。没有索引的情况的I/O量为:1000000*(10000+1)=10001000000页。在t1(c1)有索引,该索引的高度对应的高度为4的情况下,假设I/O量为:100000*(4+1)=5000000。对比一下,没有索引与有索引,两者之间的代价比约等于2000:1。相等于,假设没有索引的情况下执行需要2000s,那么有索引的情况下只需要1s。
从上面的对比当中,我们可以发现索引的重要性,在实际应用当中,80%的查询性能问题来源于没有创建索引或者没有创建合适的索引。
为什么要引入散列连接呢?假设两张表t1(c1 int,c2 int),t2(d1 int,d2 int),查询语句为select c1,d1 from t1 inner join t2 on c1=d1。如果数据库没有实现散列连接、合并连接的话,只能选择使用嵌套循环。从上篇文章中我们可以得到,对于t1的每一条记录,都需要遍历t2的每一条记录。因此,当t1的记录数数为m,t2的记录数为n,那么该查询语句访问的记录次数为m*n。当m=10000、n=10000时,那么m*n=100000000(1亿)。这是比较夸张的浪费时间。如果m是100万,n是100万,那么m*n就是1万亿次,读一万亿次记录,这是不能忍受的。
这里需要提到的一点是:我们不以读取记录的多少作为评价标准,在实际代价评估中,采用数据页(也可称为数据块,I/O的基本单位)。但是两者之间又是有联系的,假设每个页存放100个数据,那么t1的数据页为100页(10000/100),t2的数据页为100页,那么对于t1中的每一条记录,需要遍历t2的100页,加上该记录在t1中也属于一个数据页。因此,对于t1中的每一个记录,需要访问101个数据页。那么该查询的I/O量为:10000*(100+1)=1010000页。如果考虑到数据页的缓冲,情况会更加复杂。代价评估是个很复杂的课题,可能需要单独写个系列来阐述数据库查询优化系统的代价评估模型。这里我们不考虑数据页缓冲,也就相当于假设数据库缓冲区的大小仅仅为1个页。
好了,继续前面的话题。
如果t1(c1)上建立有唯一索引iut1c1,那么可以将t2作为外表,对于t2的每一条记录,使用d1的值去命中索引iut1c1对应的B树。假设该B树的高度为3层,那么对于t2的每一条记录,需要访问t1表索引iut1c1中三个页(B树的高度),加上本身在t2中属于一个页。所以,在这种情况下,查询代价为:10000*(3+1)=40000页。
我们来对比一下,没有索引与有索引,两者之间的代价对比约等于25:1(比值1010000:40000)。也可以这么认为,假设没有索引的时候执行需要25s,那么有索引的情况下只需要1s。
这里我们把话题再延展下,如果m,n都为1000000,占用的块都为10000页(1000000/100)。没有索引的情况的I/O量为:1000000*(10000+1)=10001000000页。在t1(c1)有索引,该索引的高度对应的高度为4的情况下,假设I/O量为:100000*(4+1)=5000000。对比一下,没有索引与有索引,两者之间的代价比约等于2000:1。相等于,假设没有索引的情况下执行需要2000s,那么有索引的情况下只需要1s。
从上面的对比当中,我们可以发现索引的重要性,在实际应用当中,80%的查询性能问题来源于没有创建索引或者没有创建合适的索引。
2 数据库内核使用建立临时索引的方法
大家可能听到过一个这样的概念:“在sqlserver系统中,如果用户没有创建索引,执行查询时,sqlserver会自动创建该索引。”
这里我们先撇开sqlserver到底是使用临时索引还是散列连接,我们只是对这句话加以理解。
对于上文提到的查询语句,执行过程描述如下:
1)create index itemp on t1(c1);
2)执行查询语句select c1,d1 from t1 inner join t2 on c1=d1;
3)drop index itemp;
我们来评估下代价。如上文锁描述,假设m,n都为1000000,占用的块都为10000页。
首先是计算构造索引的代价:对t1的数据进行全扫描,对于每一条记录要插入到B树中,假设插入操作平均需要使用3个页。(因为起始时,B树只有一层,插入只需要访问1页,B树两层使需要访问2页,等等)。该步骤的代价为:1000000*(3+1)=4000000页。
然后计算查询的代价,前面已经计算过:100000*(4+1)=5000000页。
所以,整个代价为4000000+5000000=9000000页。
进行对比:10000:9:5(比值10001000000:9000000:5000000)。不使用索引的代价为10000,使用临时索引的代价为9,使用用户创建的索引代价为5。
所以,我们发现使用临时索引还是个不错的选择。
3 数据库内核使用散列连接的方法
首先我们讲下散列连接的原理:
1)对t1表(称为构建表)进行全扫描,对于每一个记录,对c1值进行使用内部散列函数,然后将该数据存放到相应的散列桶。
2)开始读t2表(称为探查散列表),对于t2的每一个记录,对d1值使用同样的散列函数,得到相应的散列值,查看该桶中是否有行。
如果相应的桶中没有行,则会丢失t2中这一行记录。如果散列桶中如果有一些行呢,则会精通的检查散列连接判断是否存在合适的匹配。因为不同的值可以产生同样的散列值。找到精确匹配的值,组合成记录放入结果集中。
我们来评估下代价。
1)首先我们先看构建散列的代价,对于t1的每一个记录,一般只需要访问一个散列桶。所以该步骤的代价为:1000000*(1+1)=2000000页。
2)对于t2的每一个记录,一般只需要访问一个散列桶。所以该步骤的代价为:1000000*(1+1)=2000000页。
所以,整个代价为2000000+2000000=4000000页。
进行对比:10000:4:5(比值10001000000:4000000:5000000),不使用索引的代价为10000,使用散列连接的代价为4,使用用户创建的索引代价为5。
是不是觉得不可思议?散列连接的代价竟然比使用索引的连接还小。我们通过一个例子来验证一下:
SQL> create table t1(c1 int,c2 int);
Table created.
总结:
1 循环嵌套
t1表的记录都要在t2全部查询。
2 索引
t1表的记录在t2种合适前几页查询。
3 散列
首先利用散列函数建立散列桶,t1散列桶每条的记录在t2散列桶查询
首先利用散列函数建立散列桶,t1散列桶每条的记录在t2散列桶查询
发表评论
-
SQL查询顺序处理
2011-09-15 11:29 1625select的解析执行顺序1. from语句 2. where ... -
概念模型、逻辑模型、物理模型区别
2011-09-08 10:48 1230http://wenku.baidu.com/view/9a6 ... -
规范化-数据库设计原则
2011-09-07 10:41 1452简介: 关系数据库设计的核心问题是关系模型的设计。本文将结合具 ... -
数据库设计准则(第一、第二、第三范式说明)
2011-09-07 10:17 1276I、关系数据库设计范式 ... -
oracle日志文件及归档日志模式
2011-09-01 10:18 1758oracle数据库中分为联机日志文件和归档日志文件两种日志文件 ... -
Oracle重做日志管理
2011-09-01 09:50 1435Oracle重做日志操作是为了记录数据的改变,提供数据库 ... -
Oracle复制技术的分布式系统同步应用
2011-08-28 17:41 1292本文将结合一个实际案例,讲解Oracle复制技术在分布 ... -
oracle数据同步
2011-08-28 14:34 993首先创建一个 dblink(dat ... -
Oracle 流复制(Stream Replication)
2011-07-20 10:37 5621Stream 是Oracle 的消息队列( ... -
表分区
2011-06-30 09:21 1678分区表: 当表中的数据量不断增大,查询数据的速度就会变慢,应用 ... -
数据库大型应用解决方案总结(1)
2011-06-22 18:01 1391随着互联网应用的广泛普及,海量数据的存储和访问成为了系统设 ... -
oracle_SQL中ROWID与ROWNUM的使用
2011-06-16 10:51 1424对于 Oracle 的 rownum 问题,很多资料都说不支持 ... -
oracle函数手册
2011-06-08 09:22 1183SQL中的单记录函数1.ASCII ... -
oracle基础文档
2011-06-03 09:10 1238oracle基础文档 -
ORACLE 找回误删的数据库
2011-06-02 14:14 1367同事找回时操作的数据库为oracle 10g , 之前删除方式 ... -
为什么Oracle有时会用索引来查找数据?--强制Oracle使用最优的“执行计划”
2011-06-01 09:04 1741[摘要] 在你运用SQL语言,向数据库发布一条查询语句时,O ... -
sql编程规范与性能
2011-05-31 08:40 1276sql编程规范与性能 -
Nested Loops Join(嵌套连接)
2011-04-13 16:21 11573说明:最近找到了一个 ... -
如何看Oracle执行计划
2011-01-14 15:43 2187oracle执行计划解释 ... -
oracle中分析sql语句执行计划的方法
2011-01-14 15:36 2229如何生成explain plan? 解答:运行utl ...
相关推荐
在没有索引的情况下,散列连接相比嵌套循环连接具有明显优势。然而,如果在一个表的连接键上建立了合适的索引,散列连接的效率可能会降低。这是因为索引可以有效地支持单个值的查找,而散列连接则需要构建哈希表。 ...
本文将详细介绍三种主要的表连接方式:嵌套循环连接(Nested Loop Join,简称NL Join)、排序合并连接(Sort Merge Join,简称SM Join)以及散列连接(Hash Join)。我们将探讨它们的特点、优势与劣势,以便于在实际...
DB2提供了多种连接方法,包括嵌套循环连接(nested loop join)、合并连接(merge join)以及散列连接(hash join)。每种方法都有其适用场景和限制条件。 - **嵌套循环连接**:这是一种简单但效率较低的连接方式。它通过...
1. 嵌套循环连接块传输磁盘搜索:对于两个关系r1和r2,嵌套循环连接块传输磁盘搜索的时间复杂度取决于块的大小和关系的大小。在最坏的情况下,时间复杂度为O(20000 × 1500 + 800) = 20800,而在最好的情况下,时间...
Oracle数据库提供了多种连接方法,包括嵌套循环连接、排序合并连接、集群连接、笛卡尔连接和散列连接,以及特定情况下的索引连接。每种连接方式都有其适用场景和性能特点。 1. 嵌套循环连接(Nested Loops Join)是...
在本系列文章中,作者杨万富展示了如何使用Oracle 10g版本来分析嵌套循环执行计划,并在后续文章中会探讨散列连接和归并连接,以及IN子查询和EXISTS子查询的分析,这些都对深入理解Oracle数据库的性能调优具有重要...
试题还考察了不同类型的连接策略,包括嵌套循环连接、块嵌套循环连接、归并连接和散列连接,以及它们对块存取数的影响。了解这些连接策略有助于优化数据库查询性能。 在数据库事务管理中,可恢复调度和无级联调度是...
例如,嵌套循环连接、块嵌套循环连接、索引嵌套循环连接、排序-归并连接和散列连接各有优势和适用场景。散列连接适用于等值连接,而排序-归并连接在两表都较大且已经排序时尤为有效。 除了具体的查询优化技术,查询...
连接操作有多种方法,如嵌套循环法、索引连接、排序归并法和散列连接法。每种方法都有其适用场景,如嵌套循环法适合处理小表,而排序归并法和散列连接法则适用于大表连接。投影操作通常与σ和π操作同时进行,以减少...
- **8.4.2 位图连接索引**:介绍位图连接索引的概念及其优势。 - **8.4.3 位图转换**:解释位图转换的工作原理。 - **8.5 本章小结**:总结位图索引的关键内容。 - **8.6 测试用例**:通过测试用例验证位图索引的...
### Oracle数据库性能调优技术——深入理解嵌套循环执行计划 #### 一、概述 ...在后续的文章中,我们将继续探讨其他类型的连接方法,如散列连接和归并连接,以及更高级的主题,如IN子查询和EXISTS子查询。
连接操作的实现包括嵌套循环、排序-合并、索引连接和哈希连接。嵌套循环适用于小表,而排序-合并和索引连接适合已排序的数据,哈希连接则利用哈希函数快速匹配连接属性。 查询优化器在决定如何执行查询时,会考虑...
主动的确定使用循环嵌套、合并连接、散列连接,尽可能测试使用一种代价较小的连接方式。 如果需要在pl/sql 程序中使用动态sql,建议使用execute immediate 对于非常大的表,考虑使用表和索引的分区 如果需要在创建...
连接方法包括哈希连接、星式查询连接、星式变换连接、嵌套循环连接、排序合并连接和聚簇连接,不同的方法适用于不同的优化策略。 在提升查询效率方面,Oracle 8 引入了分区、索引、聚族和 HASH 簇等技术。分区允许...
6.6.5 散列连接算法 6.6.6 节省一些磁盘I/O 6.6.7 基于散列的算法小结 习题 6.7 基于索引的算法 6.7.1 聚簇和非聚簇索引 6.7.2 基于索引的选择 6.7.3 使用索引的连接 6.7.4 使用有排序索引的连接 ...
常见的访问方式包括全表扫描、索引范围扫描、连接操作如嵌套循环、散列连接和排序合并连接。通过分析这些执行计划,可以识别性能瓶颈并制定优化策略。 总的来说,Oracle SQL性能优化是一个综合性的过程,涉及系统...
这涉及到多种优化技术,如选择合适的索引、决定连接操作的顺序、以及是否使用嵌套循环或散列连接等。优化的目标是减少查询处理的时间和资源消耗。 执行阶段:在这个阶段,DBMS根据优化器生成的执行计划来执行查询。...
连接操作则包括嵌套循环、散列连接和排序合并连接等。 Oracle的优化器分为基于规则的优化器(RBO)和基于成本的优化器(CBO)。RBO不依赖统计数据,而是通过试探法选择最低成本路径,优先级包括ROWID读取、索引使用等。...
5. **连接优化**:Oracle支持多种连接方法,如嵌套循环、哈希连接和归并连接。选择合适的连接方式对性能有很大影响。通常,哈希连接适用于数据量相近的表,而嵌套循环更适合小表驱动大表的场景。 6. **物化视图**:...