Figure 2: The rst phase of the joins needed to execute Query 3.1 from the Star Schema benchmark on some sample data
2.对多个事实表以外键关联维度表的列进行探测,查找对应的hash table,过滤出多个position list(与被关联的列相关),然后对多个position list求交集(好比bitmap的AND盘算等),得到一个最终的position list;
Figure 3: The second phase of the joins needed to execute Query 3.1 from the Star Schema benchmark on some sample data
3.基于前面的position list,最终从事实表中找到需要投影的其他列,而通过hash table从维度表找到需要投影的其他列,hash table中的value是维度表中的position,所以可以快速定位维度表的其他列。
Figure 4: The third phase of the joins needed to execute Query 3.1 from the Star Schema benchmark on some sample data
这里的“隐式”是指,没有通过传统的join方式(两两表迭代,生成两个表团结在一起的宽行数据,再做过滤)来实现join,而是通过维持不同列的相同行之间的position对应关系来完成多个表join。与倒排索引很类似。
除此之外,动态代码生成、块IO(相比page IO,一次读取的数据量更大),针对块建立的稀疏索引(由于块较大,索引量小,可尽可能将索引数据加载到内存),倒排索引,Join索引等都可加速基于列式存储的SQL实行效率。
但是仅仅将数据按照列式存储就可以解决所有标题了吗?
列式存储本质上方便的是列式数据的读取,但当SQL的查询结果是需要行相关的数据时,怎样兼顾列式存储重构出行的数据,这和列式存储的存储格式和索引结构有很大关系。
存储格式和索引结构
典型的列式存储数据库体系有Microsoft SQL Server、C-Store (2005) / Vertica、Dremel、Apache Kudu、MonetDB等。文末的参考资料中分别对其存储结果有一些先容。这里我列举一下Apache ORC文件格式帮助对列式的存储格式和索引结构有所了解。
Apache ORC的分区索引结构如下: