关于Greenplum的查询处理

关于Greenplum的查询处理

这个主题给出了Greenplum数据库如何处理查询的概述。理解这一处理有助于编写和调优查询。

用户像对任何数据库管理系统那样将查询发送到Greenplum数据库。它们使用psql之类的客户端应用连接到Greenplum的Master主机上的数据库实例并且提交SQL语句。

理解查询规划和分发

Master接收、解析并且优化查询。作为结果的查询计划可能是并行的或者定向的。如图 1所示,Master会把并行查询计划分发到所有的Segment。而如图 2所示,Master会把定向查询计划分发到单一的一个Segment。每个Segment负责在其自己的数据集上执行本地数据库操作。

大部分的数据库操作(例如表扫描、连接、聚集和排序)都会以并行的方式在所有Segment上执行。在一个Segment的数据库上执行的每个操作都独立于存储在其他Segment数据库中的数据。

图 1. 分发并行查询计划

某些查询可能只访问单个Segment上的数据,例如单行的INSERTUPDATEDELETE或者SELECT操作或者以表分布键列过滤的查询。在这些查询中,查询计划不会被分发到所有的Segment,而是定向给到包含受影响或者相关行的Segment。

图 2. 分发定向查询计划

理解Greenplum的查询计划

查询计划是Greenplum数据库将要执行以产生查询答案的操作集合。计划中的每个节点或者步骤表示一个数据库操作,例如表扫描、连接、聚集或者排序。计划的读取和执行按照从底向上的顺序进行。

除通常的数据库操作(例如表扫描、连接等等)之外,Greenplum数据库还有一种额外的被称为移动的操作类型。移动操作涉及到在查询处理期间在Segment之间移动元组。注意并非每一个查询都需要移动操作。例如,定向查询计划就不需要通过Interconnect移动数据。

为了在查询执行期间达到最大并行度,Greenplum将查询计划的工作划分成切片。切片是Segment能够在其上独立工作的计划片段。只要有一个移动操作出现在计划中,该查询计划就会被切片,在移动的两端分别有一个切片。

例如,考虑下面涉及两个表之间连接的简单查询:

SELECT customer, amount
FROM sales JOIN customer USING (cust_id)
WHERE dateCol = '04-30-2016';

图 3展示了这个查询计划。每个Segment接收一份查询计划的拷贝并且并行地根据计划工作。

这个例子的查询计划有一个重分布移动,它在Segment之间移动元组以完成连接。重分布移动是必要的,因为customer表在Segment上按照cust_id分布,而sales表是按照sale_id分布。为了执行该连接,sales元组必须按照cust_id重新分布。该计划在重分布移动操作的两边被切换,形成了slice 1slice 2

这个查询计划由另一种称为收集移动的移动操作。收集操作表示Segment何时将结果发回给Master,Master再将结果呈现给客户端。由于只要有移动产生查询计划就会被切片,这个计划在其最顶层也有一个隐式的切片(slice 3)。不是所有的查询计划都涉及收集移动。例如,一个CREATE TABLE x AS SELECT...语句不会有收集移动,因为元组都被发送到新创建的表而不是发给Master。

图 3. 查询切片计划

理解并行查询及执行

Greenplum会创建若干数据库进程来处理查询的工作。在Master上,查询工作者进程被称作查询分发器(QD)。QD负责创建并且分发查询计划。它也收集并且表达最终的结果。在Segment上,查询工作者进程被称为查询执行器(QE)。QE负责完成它那一部分的工作并且与其他工作者进程交流它的中间结果。

对查询计划的每一个切片至少要分配一个工作者进程。工作者进程独立地工作在分配给它的那部分查询计划上。在查询执行期间,每个Segment将有若干进程并行地为该查询工作。

为查询计划的同一个切片工作但位于不同Segment上的相关进程被称作团伙。随着部分工作的完成,元组会从一个进程团伙流向查询计划中的下一个团伙。这种Segment之间的进程间通信被称作Greenplum数据库的Interconnect组件。

图 4展示了图 3所示查询计划在Master和两个Segment实例上的查询工作者进行。

图 4. 查询工作者进程