关系型数据库工作原理-查询优化器之归并连接(14)

本文翻译自Coding-Geek文章:《 How does a relational database work》。原文链接:http://coding-geek.com/how-databases-work/#Buffer-Replacement_strategies

本文翻译了如下章节, 介绍数据库查询优化器的归并连接的实现原理:
这里写图片描述

归并连接-Merge join

这里写图片描述

本章的内容与前面讨论过的归并排序非常类似。不同的是不用从两张关系表中拿出所有的数据,我们仅需要拿出相等的数据即可。算法基本思路是:
1. 先比较两张关系表的第一个元素。
2. 如果第一个元素相等,将这两条数据放到结果集中。然后比较下一个元素。
3. 如果不相等,取小的元素所在表的下一个元素,下一个元素可能就匹配了(译者注:在做merge join前先对两张表做由小到大的排序)。
4. 重复前面的几步操作,直到其中一张表的数据比较完了为止。

这个算法能正常运作的前提是,两张关系表的数据都已经排好序,在比价的过程中不需要回溯前面的元素。

这个是算法是一个简化版,它不需要考虑相同的数据在两组数据中出现多次的情况,即不考虑多次重复匹配。一个真实的归并连接算法仅仅因为这个问题就会复杂很多。这也是我选择一个简化版算法原因(译者注:重要的是讲清楚算法原理)。

如果两张关系表已排好序,那merge join的时间复杂度是O(N+M)。

如果两张关系表都需要排序,那么时间度是排序需要的消耗:O(N*Log(N) + M*Log(M))。

作为一个计算机专业的极客,我提供一个处理重复数据匹配的算法(我不保证它100%正确):

mergeJoin(relation a, relation b)
  relation output
  integer a_key:=0;
  integer b_key:=0;

  while (a[a_key]!=null or b[b_key]!=null)
    if (a[a_key] < b[b_key])
      a_key++;
    else if (a[a_key] > b[b_key])
      b_key++;
    else //Join predicate satisfied
    //i.e. a[a_key] == b[b_key]

      //count the number of duplicates in relation a
      integer nb_dup_in_a = 1:
      while (a[a_key]==a[a_key+nb_dup_in_a])
        nb_dup_in_a++;

      //count the number of duplicates in relation b
      integer dup_in_b = 1:
      while (b[b_key]==b[b_key+nb_dup_in_b])
        nb_dup_in_b++;

      //write the duplicates in output
       for (int i = 0 ; i< nb_dup_in_a ; i++)
         for (int j = 0 ; i< nb_dup_in_b ; i++)    
           write_result_in_output(a[a_key+i],b[b_key+j])

      a_key=a_key + nb_dup_in_a-1;
      b_key=b_key + nb_dup_in_b-1;

    end if
  end while
发布了113 篇原创文章 · 获赞 183 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/ylforever/article/details/79838679