`
newleague
  • 浏览: 1492949 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

散列连接,索引,嵌套循环

SQL 
阅读更多
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%的查询性能问题来源于没有创建索引或者没有创建合适的索引。
   

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散列桶查询
    
分享到:
评论

相关推荐

    oracle 数据库性能调优技术 4 中文

    在没有索引的情况下,散列连接相比嵌套循环连接具有明显优势。然而,如果在一个表的连接键上建立了合适的索引,散列连接的效率可能会降低。这是因为索引可以有效地支持单个值的查找,而散列连接则需要构建哈希表。 ...

    Oracle数据库3种主要表连接方式对比

    本文将详细介绍三种主要的表连接方式:嵌套循环连接(Nested Loop Join,简称NL Join)、排序合并连接(Sort Merge Join,简称SM Join)以及散列连接(Hash Join)。我们将探讨它们的特点、优势与劣势,以便于在实际...

    db2 SQL优化

    DB2提供了多种连接方法,包括嵌套循环连接(nested loop join)、合并连接(merge join)以及散列连接(hash join)。每种方法都有其适用场景和限制条件。 - **嵌套循环连接**:这是一种简单但效率较低的连接方式。它通过...

    16337341(朱志儒)数据库系统作业51

    1. 嵌套循环连接块传输磁盘搜索:对于两个关系r1和r2,嵌套循环连接块传输磁盘搜索的时间复杂度取决于块的大小和关系的大小。在最坏的情况下,时间复杂度为O(20000 × 1500 + 800) = 20800,而在最好的情况下,时间...

    Oracle数据库表连接笔记.doc

    Oracle数据库提供了多种连接方法,包括嵌套循环连接、排序合并连接、集群连接、笛卡尔连接和散列连接,以及特定情况下的索引连接。每种连接方式都有其适用场景和性能特点。 1. 嵌套循环连接(Nested Loops Join)是...

    oracle数据库性能调优(3)

    在本系列文章中,作者杨万富展示了如何使用Oracle 10g版本来分析嵌套循环执行计划,并在后续文章中会探讨散列连接和归并连接,以及IN子查询和EXISTS子查询的分析,这些都对深入理解Oracle数据库的性能调优具有重要...

    2021-数据库系统原理试题.docx

    试题还考察了不同类型的连接策略,包括嵌套循环连接、块嵌套循环连接、归并连接和散列连接,以及它们对块存取数的影响。了解这些连接策略有助于优化数据库查询性能。 在数据库事务管理中,可恢复调度和无级联调度是...

    SQL Server的查询优化.pdf

    例如,嵌套循环连接、块嵌套循环连接、索引嵌套循环连接、排序-归并连接和散列连接各有优势和适用场景。散列连接适用于等值连接,而排序-归并连接在两表都较大且已经排序时尤为有效。 除了具体的查询优化技术,查询...

    数据库系统原理-第五章 查询处理与优化.doc

    连接操作有多种方法,如嵌套循环法、索引连接、排序归并法和散列连接法。每种方法都有其适用场景,如嵌套循环法适合处理小表,而排序归并法和散列连接法则适用于大表连接。投影操作通常与σ和π操作同时进行,以减少...

    (E文)基于成本的Oracle优化法则.pdf

    - **8.4.2 位图连接索引**:介绍位图连接索引的概念及其优势。 - **8.4.3 位图转换**:解释位图转换的工作原理。 - **8.5 本章小结**:总结位图索引的关键内容。 - **8.6 测试用例**:通过测试用例验证位图索引的...

    oracle 数据库性能调优技术 3 中文

    ### Oracle数据库性能调优技术——深入理解嵌套循环执行计划 #### 一、概述 ...在后续的文章中,我们将继续探讨其他类型的连接方法,如散列连接和归并连接,以及更高级的主题,如IN子查询和EXISTS子查询。

    第一章绪论数据库系统基础ppt课件.ppt

    连接操作的实现包括嵌套循环、排序-合并、索引连接和哈希连接。嵌套循环适用于小表,而排序-合并和索引连接适合已排序的数据,哈希连接则利用哈希函数快速匹配连接属性。 查询优化器在决定如何执行查询时,会考虑...

    SQL普查优化信息汇总

    主动的确定使用循环嵌套、合并连接、散列连接,尽可能测试使用一种代价较小的连接方式。 如果需要在pl/sql 程序中使用动态sql,建议使用execute immediate 对于非常大的表,考虑使用表和索引的分区 如果需要在创建...

    Oracle8数据库系统的查询优化.pdf

    连接方法包括哈希连接、星式查询连接、星式变换连接、嵌套循环连接、排序合并连接和聚簇连接,不同的方法适用于不同的优化策略。 在提升查询效率方面,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 使用有排序索引的连接 ...

    高性能SQL优化 Oracle

    常见的访问方式包括全表扫描、索引范围扫描、连接操作如嵌套循环、散列连接和排序合并连接。通过分析这些执行计划,可以识别性能瓶颈并制定优化策略。 总的来说,Oracle SQL性能优化是一个综合性的过程,涉及系统...

    Oracle高性能SQL优化.ppt

    连接操作则包括嵌套循环、散列连接和排序合并连接等。 Oracle的优化器分为基于规则的优化器(RBO)和基于成本的优化器(CBO)。RBO不依赖统计数据,而是通过试探法选择最低成本路径,优先级包括ROWID读取、索引使用等。...

    Oracle查询优化.rar

    5. **连接优化**:Oracle支持多种连接方法,如嵌套循环、哈希连接和归并连接。选择合适的连接方式对性能有很大影响。通常,哈希连接适用于数据量相近的表,而嵌套循环更适合小表驱动大表的场景。 6. **物化视图**:...

    oracle数据访问

    在处理多表连接时,Oracle提供了多种连接方式,包括嵌套循环连接(Nested Loop Join)、哈希连接(Hash Join)和归并连接(Merge Join)。连接方式的选择取决于数据量、内存可用性以及表之间的关系。通过SQL提示...

Global site tag (gtag.js) - Google Analytics