`

数据仓库的模型和join算法

 
阅读更多
   数据仓库中经典模型主要有两种:一种是雪花模型,另外一种就是星座模型。简单的来说,雪花模型中是一个事实表,和若干个维度表,事实表通过外键和维度表关联。星座模型中存在着不止一个事实表,引用若干维度表,事实表直接也相互关联,目前数据仓库领域公认的TPCH测试集所使用的数据就是一个星座模型。从某种意义上说星座模型是对雪花模型的一种优化,因为在雪花模型中,唯一的事实表很可能需要只做到了第三范式,如果进一步优化达到第四范式,雪花模型就演变成了星座模型。
   有过数据库调优经验的人会发现,在数据库中,第三范式有些时候可能性能比第四范式要好,具体来说,这个取决于具体的查询。第三范式相对第四范式来说,省去了两个表做连接的操作,但是付出的代价就是数据有冗余,在某些情况下,查询的性能要好于两个表之间的连接。因此,对于一个数据仓库的建模来说,具体是雪花模型还是星座模型,具体取决于实际的应用。在工业界的TPCH测试集中,整个的数据库的schema就是一个星座模型,两张事实表:lineitem和order表,其余均为维度表,表直接通过外键关联。TPCH的测试实例包括22个SQL,其中有2条SQL是针对lineitem表的单表查询,另外的20条SQL都涉及到了join。在这20条SQL中,其中有:一条SQL完全是对于维度表的查询;另外有一条SQL是对lineitem的查询,但是涉及到了子查询,这个简单的子查询一般在查询优化时,都会被上提作为一个左半连接;剩下的18条则都涉及到了内连接。所以,一个出色的数据库/数据仓库产品必须很好的处理这些join才能提供给有说服力的测试数据。
    因此,在这里,就不得不说说数据库中的join算法。join算法是一个很古老的话题,但是,也是一个很活跃的话题。
    目前,基本的传统关系数据库都提供了多种join算法。最简单的是nestloop,具体伪码如下:
    for each row R1 in the outer table
    for each row R2 in the inner table
        if R1 joins with R2
         {
            return (R1, R2)
          }
    nextloop适用于数据比较小的情况下使用,为了处理更大的数据,一般还都提供了基于hash的join和基于sort的merge-join。hash-join先选择一个小表作为outer table建立一张hash表,然后针对inner table 的每条记录在hash表中进行查找,很显然,hash表的查找算法复杂度为O(1),但是引入了建立hash表的代价;而merge-join则一般对两个表进行外部多路归并排序,然后,读取两个有序文件来做join。具体的算法这里就不一一列出了。
    这里说的数据较小,并不等价于说表很小,而是说join这个操作符所作用的数据很小。举个例子,对于SQL: select * from t1 inner join t2 on key1 where t1.key2 = a and t2.key3 = b,其中key2 和key3都不是索引或是键。一般来说,数据库会为这条SQL生成这样一个查询计划:
                          join
                        /      \
                       /        \
           filter(key2=a)     filter (key3 = b)
                     /            \
                    /              \
                 scan t1          scan t2
join的输入实际上是两个filter操作符的输出,而filter的输入来自下层的scan 操作符。数据库在确定采用何种join的算法时,对各种join算法的代价进行计算,选择最小的那个。
   一般来说,join算法中, nestloop的启动代价比较小,但是运行的代价比较大,因为nestloop这个操作符启动时的需要做的初始化步骤比较少,而对于hash-join和merge-join则需要一些准备工作,hash-join一般都需要初始化一个内置的hash表。merge-join需要排序。对于数据量超过一定阈值时,数据库一般倾向于根据代价来选择hash-join或是sort-merge-join (具体如何计算代价,回头有时间结合PG的源码再写一篇博客)。
    目前,PGSQL提供了前面提到的这些join算法,mysql 5.1只提供了nextloop(好久没有看mysql的源码,不清楚是否新版本的mysql在这方面的改进,抱歉)。相对来说,在数据量较大的情况下,nextloop的操作代价远大于hash-join或是sort-merge-join。假设这么一种情况:如果数据库所能使用内存只有L个单位(在PG中默认的一个单位一般是8K大小),而join运算符的outer table和 inner table分别需要的内存为M个单位和N个单位。而我们知道数据库都会为表提供缓存,对于这些缓存也有相应的替换算法,例如PGSQL中就提供了clock-wise算法,clock-wise可以看做是在FIFO的基础在再多给一次机会。而mysql的表的缓存管理主要取决于表的引擎类型,具体算法可以google。我们可以简单的将这些算法看做是FIFO。以nextloop为例,假设读取或是写入一个单位大小的磁盘数据需要一次IO,如果M和N都小于L,那么就可以将一个表先读入内存,然后逐块读入另外一个表的数据,来做join,这样操作的代价为M+N次IO,而如果N和M都大于等于L,则会因为页面的替换算法,不可避免的将已读取的页的换出,这样的操作代价就是M*N次IO。 这样的结论同样也适合hash join。而sort-merge-join来说,在内存有限的情况下,操作的复杂度则是O(M*log(M)+N*log(N))。在数据量比较大的情况下,很明显,merge-join的操作代价小很多。
   在这里需要指出的是,之所以把一个复杂的查询代价简化成IO代价,主要因为是目前在单机上,磁盘的访问速度远低于内存和CPU上的cache,数据仓库中SQL主要的开销还是在磁盘上。
   因此,如果join需要处理相对比较大的数据时,hash-join和smerge-join要比nextloop 快很多。所以,在这方面PGSQL相对来说要优于mysql。因此,从这方面来说,目前商业的MPP系统(例如Greenplum和AsterData)选择PGSQL做为内部的节点不是没有理由的。
   而在分布式的数据仓库中,为了处理join,也设计了若干种算法。这些算法和传统关系数据库中join算法有着很大的联系。比较经典的分布式数据仓库(例如teradata)一般使用share-nothing的架构,相关的研究论文可以搜索gamma系统,威斯康星麦迪逊分校在这个项目上发表了诸多用意义的论文,大家可以google。
   share-nothing的数据仓库,简单的架构可以看作是一个中心节点和若干从节点,中心节点将查询处理之后,产生查询计划,然后将查询计划分发到各个节点执行,从节点上存储着水平分片的数据,从节点执行查询计划之后,将结果返回给中心节点,中心节点进一步处理之后将结果返回给用户。
    为了处理join, share-noting的分布式数据仓库中主要使用了三种常见的并行join算法:基于排序的并行join的算法,将参与join的算法按照连接的字段进行排序之后再分片,将各个分片分发到各个从节点,然后各个从节点执行sort-merge-join操作;基于hash的并行join算法,则在各个从节点上采用统一的hash算法进行分桶,然后将各个桶分发到对应的从节点上,从节点上执行join算法;全复制的并行join算法,这种算法适用于某个连接的表比较小的情况下,这个小表会在每个从节点上都有一个副本,然后直接执行join算法。
    之前,有同学问我:一个只有两个表做join的SQL在mysql上半天没有出结果,但是在N个datanode的hadoop上很快就有了结果,这个是为什么?对于这个答案,其实很简单,在这种情况下mysql上做join,操作代价退化为O(M*N),如果在hadoop上先对两个表直接hash分桶,然后join,操作的复杂度不过是O(N+M)(具体的复杂度可以根据实际的算法实现进行分析),很明显,这种简单的分布式join算法要明显快于单台的nextloop。
    可能这几种并行join算法比较古老,但是,如果你经常使用hadoop进行表之间的连接操作,你就会发现这三种算法会经常使用到。而hive中更是直接使用了mapjoin,事实上这就是经典的分布式并行数据仓库中使用的全复制的并行join算法。而在很多大数据的职位面试中,这些算法更是被经常提到,因此,在”大数据“这个烂大街的术语的时代里,这些算法应当成为常识。
   (本人对这方面理解不深,欢迎拍砖)
分享到:
评论

相关推荐

    hash join算法原理

    Hash join算法的一个基本思想就是根据小的row sources(称作build input,我们记较小的表为S,较大的表为B) 建立一个可以存在于hash area内存中的hash table,然后用大的row sources(称作probe input) 来探测前面所建...

    hash join 原理和算法

    hash join 原理和算法 1.Hash Join概述 2.Hash Join原理 3.Hash Join算法 4.Hash Join的成本

    论文研究-一种改进的闪存数据库Sort-Merge-Join算法.pdf

    在对传统的Sort-Merge-Join算法进一步研究的基础上,提出了一种改进的闪存数据库Sort-Merge-Join算法。该算法只对小关系进行外...通过理论分析和与传统Sort-Merge-Join算法在闪存上的比较实验,证明了该算法的优越性。

    第8章基于Hadoop的数据仓库Hive作业.pptx

    本资源摘要信息主要介绍了Hadoop基于Hive的数据仓库作业,涵盖了Hive的基本概念、数据仓库的概念、Hive的数据模型、Hive的查询语言、Hive的数据处理、Hive的优化技术等。 1.Hive的基本概念 Hive是一个基于Hadoop的...

    hash join算法

    oracle hash join算法原理

    Hash join算法原理

    Hash join算法原理 详细讲述了oracle sql语句的连接方式 对于sql调优提高有很大帮助

    【MapReduce篇06】MapReduce之MapJoin和ReduceJoin1

    MapJoin 和 ReduceJoin 都可以应用于数据分析和处理领域,例如,在数据仓库和数据挖掘等领域。MapJoin 可以应用于数据聚合和数据分析,而 ReduceJoin 可以应用于数据集成和数据挖掘。 在实际应用中,MapJoin 和 ...

    MySQL中Nested-Loop Join算法小结

    数据库中JOIN操作的实现主要有三种:嵌套循环连接(Nested Loop Join),归并连接(Merge Join)和散列连接或者哈稀连接(Hash Join)。其中嵌套循环连接又视情况又有两种变形:块嵌套循环连接和索引嵌套循环连接。

    大数据算法视频课程+课件

    大数据算法这门课程旨在通过讲授一些大数据上基本算法设计思想,包括概率算法、I/O有效算法和并行算法,让听课的同学们接触到和传统算法课程不一样的算法设计与分析思路,并且以最新的研究成果为导向,让参与这门...

    分布式数据仓库Hive大全

    1. HIVE结构 6 1.1 HIVE架构 6 1.2 Hive 和 Hadoop 关系 7 1.3 Hive 和普通关系数据库的异同 8 1.4 HIVE元数据库 9 ...9.8.3 大表Join的数据偏斜 60 9.9 合并小文件 62 9.10 Group By 62 10. HIVE FAQ: 62

    论文研究-Part-Join:基于划分的字符串相似性连接.pdf

    为此,提出了一种基于划分的算法Part-Join,它从频率向量、字母表、频率分布三方面对数据集进行子集划分,并给出子集间的过滤策略用于排除不相似的字符串对。扩展实验表明,Part-Join比已有算法Pass-Join效率提高了...

    基于统计方法的Hive数据仓库查询优化实现

    Map/Reduce是海量离线数据分析中广泛应用的并行编程模型.Hive数据仓库基于Map/Reduce实现了查询处理引擎,然而Map/Reduce框架在处理偏斜数据时会出现工作负载分布不均的问题.均衡计算模型(computation balanced model...

    Fork-Join实时任务图模型的可行性:硬度和算法

    Fork-Join实时任务图模型的可行性:硬度和算法

    基于阿里云搭建实时数据仓库项目项目需求及架构设计.pdf

    本文档主要讲述基于阿里云搭建实时数据仓库项目的需求和架构设计。该项目的目的是学习搭建一个实时数据仓库,掌握数据采集、存储、计算、输出、展示等整个业务流程。 课程目标 * 学习搭建一个实时数据仓库,掌握...

    ArcGis导入EXCEL数据,join之后为什么是NULL.doc

    这是因为在 ArcGIS 中,join 操作需要基于唯一标识码的字段进行关联,而 EXCEL 数据中的字段名称、格式和内容都可能会影响 join 操作的结果。 第一种解决方案是,在 ArcCatalog 中,添加 OLE DB 连接,选择 ...

    Mycat与Mysql跨库JOIN与性能测试

    ER Join是指使用实体关系模型来描述数据库之间的关系,以便从多个数据库中获取数据。ER Join可以分为两种:一对一ER Join和一对多ER Join。 一对一ER Join是指将两个数据库表连接起来,以便从两个数据库中获取数据,...

    饿了么推荐算法演进及在线学习实践(24页).pdf

    在线学习算法还可以实现实时多数据流join和实时产出多数据融合的细粒度事实数据。 技术栈 技术栈是指在线学习实践中所使用的技术架构。技术栈包括数据源、数据采集、消息管道、数据处理、数据存储、ekv、Storm、...

    inner join、 left join 、right join、 outer join之间的区别

    inner join、 left join 、right join、 outer join之间的区别

Global site tag (gtag.js) - Google Analytics