简介
在决策辅助系统(DSS),OLAP和分析类数据仓库应用中,人们经常使用维度数据模型,比如星型和雪花模型。”维度”即人们观察数据的角度,以销售数据为例,常用的维度包括“销售时间”,“销售地点”等。即人们希望根据“时间”这个维度来查询某一段时间内的销售数据;或者”地点”这个维度,查询某一地区的销售情况。采用这种数据模型,每一个维度,对应于数据库事实表的一列。因此一张事实表会包含多个维度列。
在查询的时候,查询条件中可能包含也可能不包含所有的维度。比如一张销售表(sales),有如下几个维度:销售日期,销售门店,销售物品。用户可能需要查找在一个星期内,针对某项销售物品,所有销售门店的销售情况(在这种情况下,门店这个维度列不在查询条件中)。多数传统数据库对此类查询采用全表扫描,虽然专门的列式分析类数据库可以以极高的速度对表进行扫描,但依旧需要扫描大量数据,再过滤掉。
MDAM(Multi-Dimensional Access Method)是一种可以高效访问数据的创新方法,避免了不必要的全量数据扫描。采用这种方法可以非常高效地支持以上描述的分析类查询场景。
MDAM的原理介绍
现在让我先定义好本文需要的例子表sales。
列名 | 含义 | 是否主键 |
Dept | 部门 | Y |
Date | 销售日期 | Y |
Item_class | 销售物品分类 | Y |
Store | 销售门店 | Y |
Item | 销售物品 | N |
Total_sales | 销售量 | N |
表Sales的主键为(dept, date, item_class, store)
大多数数据库采用BTree组织物理数据的存储,B-Tree是一个非常好的查询数据结构,支持两种高效的查询:
· 给定key,快速返回Value。B-Tree的本身特点。
· 给定Range,快速返回范围内的数据集合
· 即返回key ? [ a, b] 范围内的集合
o 因为数据是根据key聚集在一起,相邻的数据在同一个Btree block里面,一次IO可以全部读出来(单个Block,或者顺序读多个block,都比较高效)
了解了Btree的特点后,我们可以发现,当查询条件包含所有主键列时,将非常高效。因为主键做lookup操作是非常快的。因为当知道key的值,从二叉树中查找一个值是二叉树最擅长的事情。当给定dept,查询某个时间范围时,二叉树也非常高效。
然而,当查询条件没有给定dept,或者在主键组合中靠前的一个或几个列时,BTree就无法支持这种查询,因而只能进行全表扫描。这是很多数据库的问题,一般情况下,需要建立二级索引来解决问题。但索引带来很多的副作用,空间的膨胀,写入速度下降等。
EsgynDB采用MDAM技术来解决这个问题,更加高效地利用底层数据结构,而且无需额外的索引。
接下来,我们分几种典型情况,来讲解MDAM的工作机制。
场景一,Range predicates on intervening key columns
给定如下一个SQL查询:
SELECT date, sum(total_sales)
FROM Sales
WHERE dept = 10
AND date BETWEEN "06/01/95" and "06/30/95"
AND item_class = 20
AND store = 250
GROUP BY dept, date;
假设95年6月1日,到95年6月30日之间,表sales中存在的日期值为( ‘06/04/95’, 06/07/95’, ‘06/18/95’, ‘06/22/95’ )这样四个,即UEC(Unique Entity Count)为4。
多数数据库将走全表扫描,MDAM则采取‘跳跃扫描’的方法,可以极大提高数据访问效率。
MDAM扫描的工作流程如下:
首先查找date大于06/01/95,小于06/30/95,并且dept = 10的第一个匹配的date,找到06/04/95这个值。
用dept=10, date=“06/04/95”, item_class=20, store = 250 作为查询条件进行查找。这些都是符合条件的结果集,直接输出
然后,查找下一个符合dept=10,date在6月1日和6月30日之间的date值,应该找到06/07/95,然后再用dept = 10, date = ‘06/07/95’, item_class=20,store=250作为条件进行查询。以此类推。
性能分析
如果item_class和store的UEC很大,有很多值,那么MDAM将避免扫描数以千计甚至千万计的行。
每次access的代价相对这些扫描是比较小的,前提条件是access的次数相对比较少。Access的次数由date的UEC决定,因此,实践中,要求组合键靠前的colum的UEC应该尽量小,才可以高效的执行MDAM。
场景二,Missing predicates on leading or intervening key columns.
在来看如下这个SQL查询,第一列dept没有查询条件,很多数据库只能走全表扫描。
SELECT date, sum(total_sales)
FROM sales
WHERE
date between "06/01/95" and "06/30/95"
and item_class = 20
and store = 250
GROUP BY dept, date;
MDAM的执行方式:
假设dept的值从1到100
MDAM首先查找dept > MIN_VAL的一个个值,找到1
然后构造这样一个查询条件
dept=1, date="06/04/95", item_class=20, store=250,查询出满足条件的结果。
然后根据date的其他值构造查询
dept=1, date="06/11/95", item_class=20, store=250
dept=1, date="06/18/95", item_class=20, store=250
dept=1, date="06/25/95", item_class=20, store=250
当所有date都使用了之后,将dept的值加一。用dept=2继续上面的步骤。
dept=2, date="06/04/95", item_class=20, store=250
dept=2, date="06/11/95", item_class=20, store=250
dept=2, date="06/18/95", item_class=20, store=250
dept=2, date="06/25/95", item_class=20, store=250
这种跳跃的方式将避免扫描大量的无效数据,极大地提高了数据访问的效率。
以上通过两个例子,大致介绍了MDAM技术最基本的工作原理。在实践中,用户查询往往会十分复杂,尤其对于OLAP项目,很多项目使用了复杂的框架技术,SQL语句很多情况下是机器自动生成,使得其WHERE条件非常复杂,比如:
(
(item_class=10 and date between "06/04/95" and 06/25/95)
OR dept IN (2, 4, 5)
)
AND
(
(dept=4 and item_class=5)
OR
(item_class IN (5,10) and (date="06/04/95" OR dept=2))
)
EsgynDB在SQL编译阶段,可以将任意复杂的WHERE表达式转换为disjunctive normal form ( https://en.wikipedia.org/wiki/Disjunctive_normal_form )。并能够消除重复,对每一个disjunct运用MDAM访问方式,并将最终结果集合并(Union)。上例中的复杂查询条件将变化为:
(dept=4 and date between "06/04/95" and "06/25/95"
and item_class=10 and item_class=5)
OR (date between "06/04/95" and "06/25/95" and
date="06/04/95" and item_class=10 and
item_class IN (5,10))
OR (dept=2 and date between "06/04/95" and "06/25/95"
and item_class=10 and item_class IN (5,10))
OR (dept IN (2,4,5) and dept=4 and item_class=5)
OR (dept IN (2,4,5) and date="06/04/95"
and item_class IN (5,10)
OR (dept IN(2,4,5) and dept=2 and item_class IN (5,10))
这种逻辑表达式,全部由OR组成,每个部分都可以利用MDAM进行高效执行,再把结果合并即可。因此EsgynDB的MDAM可以处理任意形式的布尔逻辑表达式组成的查询条件。
结束语
MDAM是EsgynDB拥有的一项专利技术,并已经贡献给Apache基金会,开源出来。它是一种非常巧妙的数据访问方法,在很多场景下避免了索引的创建,同时提供对OLAP分析类查询的高效支持。通用数据库面临着千变万化的用户查询需求,一项技术并非能解决所有问题,MDAM和其他EsgynDB的核心技术协作,已经为全球用户解决了许多数据访问的难题,代表了EsgynDB技术上的成熟性。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30206145/viewspace-2149732/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30206145/viewspace-2149732/