druid-docs-cn/Querying/queryexecution.md

4.8 KiB
Raw Blame History

查询执行

[!WARNING] 本文档描述了Druid如何执行 原生查询,但是由于 Druid SQL 查询被转换为原生查询因此本文档也适用于SQL运行时。有关如何将SQL查询转换为原生查询的信息请参阅 SQL查询转换 页面。

Druid的查询执行方法因查询的 数据源类型 而异。

数据源类型

table

直接在 表数据源 上操作的查询使用由Broker进程引导的分散-聚集方法执行。过程如下:

  1. Broker根据 "interval" 参数确定哪些 与查询相关。段总是按时间划分的,因此任何间隔与查询间隔重叠的段都可能是相关的。
  2. 如果输入数据使用 single_dim partitionsSpec 按范围分区并且过滤器与用于分区的维度匹配则Broker还可以根据 "filter" 进一步修剪段列表。
  3. Broker在删除了查询的段列表之后将查询转发到当前为这些段提供服务的数据服务器如Historical或者运行在MiddleManagers的任务
  4. 对于除 Scan 之外的所有查询类型,数据服务器并行处理每个段,并为每个段生成部分结果。所做的具体处理取决于查询类型。如果启用了 查询缓存则可以缓存这些部分结果。对于Scan查询段由单个线程按顺序处理结果不被缓存。
  5. Broker从每个数据服务器接收部分结果将它们合并到最终结果集中并将它们返回给调用方。对于Timeseries和Scan查询以及没有排序的GroupBy查询Broker可以以流式方式执行此操作。否则Broker将在返回任何内容之前完全计算结果集。

lookup

直接对 Lookup数据源(没有联接) 进行操作的查询使用查询的本地副本在接收查询的Broker上执行。所有注册的Lookup表都预加载到Broker的内存中。查询运行单线程。

使用Lookup作为联接的右端输入的查询的执行是以依赖于其"base"(最左下角)数据源的方式执行的,如下面的 join 部分所述。

union

直接在 union数据源 上操作的查询在Broker上被拆分为属于union的每个表的单独查询。这些查询中的每一个都单独运行Broker将它们的结果合并在一起。

inline

直接在 内联数据源 上操作的查询在接收查询的Broker上执行。查询运行单线程。

使用内联数据源作为联接的右端输入的查询的执行方式取决于它们的"base"(最左下角)数据源,如下面的 join 部分所述。

query

[query数据源] 是子查询, 每个子查询都被当作它自己的查询来执行, 结果会返回给Broker。然后Broker继续处理查询的其余部分就像子查询被内联数据源替换一样。

在大多数情况下子查询结果在其余查询继续之前在Broker上的内存中完全缓冲这意味着子查询按顺序执行。以这种方式在给定查询的所有子查询中缓冲的行总数不能超过 druid.server.http.maxSubQueryRows 属性。

有一个例外:如果外部查询和所有子查询都是 groupBy 类型,则可以以流式方式处理子查询结果,并且 druid.server.http.maxSubQueryRows 限制不适用。

join

使用广播hash-join方法处理 联接数据源

  1. Broker执行输入join的任何子查询query部分所述并用inline数据源替换它们。
  2. Broker将连接树如果存在展平为"基本"数据源(最左下角的一个)和其他叶数据源(其余部分)。
  3. 使用与基本数据源相同结构的查询执行将单独继续执行。如果基数据源是一个表,则像往常一样根据"interval"修剪段并通过将查询并行地转发到所有相关的数据服务器在集群上执行查询。如果基数据源是Lookup或Join数据源包括将内联子查询作为结果的内联数据源则查询将在Broker本身上执行。基查询不能是Union因为当前不支持Union作为Join的输入。
  4. 在开始处理基数据源之前将执行查询的服务器首先检查所有非基叶数据源以确定是否需要为即将到来的哈希联接生成新的哈希表。目前Lookup不需要构建新的哈希表因为它们是预加载的但Inline数据源需要。
  5. 使用与基本数据源相同结构的查询执行将单独继续执行, 但有一个附加条件在处理基本数据源时Druid服务器将使用从其他连接输入构建的哈希表来逐行生成联接结果查询引擎将对联接的行而不是基本行进行操作。