概述
2018年在工作中接触了Phoenix,研究之后发现其实现原理与我初步的理解不太一样,相信对于很多做过数据库开发、用过HBase、又刚刚接触Phoenix的人来说也是这样,本文说几个点供大家参考,如果有误也希望大家能帮忙指出。
谁来做执行计划?
在一般的关系型数据库中,数据库优化器会根据表和索引情况、统计信息等做出SQL的执行计划,这个过程是在服务端进行的。
Phoenix也一样有执行计划,类似也是根据表和索引情况、统计信息等将SQL转换成HBase的Scan或Put操作。而不一样的是4.4版本之前的Phoenix是“fat Client”,生成执行计划的过程只能在客户端完成,这会导致高并发情况下客户端在生成执行计划阶段耗费较多资源和时间,需要通过一些手段进行优化,我将在另一篇文章中提到。
从4.4版本开始,Phoenix提供了一个独立的Query Server,让客户端变成"thin client",我们尚未在生产使用该特性,不过已知很多大厂在生产使用,相信会有不错的效果。
Scan还是Get?
按照以往做rowkey查询的经验来考虑,对于where key in ('A','B','C',…)这种条件的实现可以使用Get(LIst)的方式,虽然Get也是特殊的Scan,但至少可以使用现成的API。
然而Phoenix并不是这样的,执行计划产生一系列Scan向服务端发起读请求,可能会分多个阶段,服务端使用协处理器并行执行每个阶段的多个Scan,可能是FULL、Range、Skip几种类型。对于“in常量清单”的查询,最优情况会是Skip Scan。
Phoenix中的视图
在关系型数据库中有视图(View)的概念,即可以将一段Select语句定义成一个虚拟表,可以在SQL中被使用,对视图做查询时相当于一个子查询,视图的定义可以非常复杂。
而Phoenix虽然也有视图,但不支持复杂的定义,如join、union 之类的关键字,以及聚合函数,只能是一个简单的SQL语句。受制于此,视图的功能也就限于增加简单的计算列、用Where条件筛选行、select 筛选列的动作,应用场景会因此受到限制。
A VIEW may be defined over only a single table through a simple SELECT * query. You may not create a VIEW over multiple, joined tables nor over aggregations (PHOENIX-1505, PHOENIX-1506).