Druid SQL文档

转载:http://druid.io/docs/0.14.0-incubating/querying/sql.html

SQL

内置SQL是一项实验性功能。此处描述的API可能会发生变化。

Apache Druid(孵化)SQL是一个内置的SQL层,是Druid原生的基于JSON的查询语言的替代品,由基于Apache Calcite的解析器和规划器提供支持。Druid SQL将SQL转换为查询Broker(您查询的第一个进程)上的本机Druid查询,然后将其作为本机Druid查询传递给数据进程。除了在Broker上转换SQL的(轻微)开销之外,与本机查询相比,没有额外的性能损失。

要启用Druid SQL,请确保已druid.sql.enable = true在common.runtime.properties或Broker的runtime.properties中设置。

查询语法

每个德鲁伊数据源都显示为“德鲁伊”模式中的表格。这也是默认模式,因此可以将德鲁伊数据源引用为druid.dataSourceName或者简单引用dataSourceName

可以选择使用双引号引用数据源和列名等标识符。要在标识符中转义双引号,请使用另一个双引号,例如"My ""very own"" identifier"。所有标识符都区分大小写,并且不执行隐式大小写转换。

文字字符串应引用单引号,如'foo'。具有Unicode转义的文字字符串可以写成U&'fo\00F6',其中十六进制的字符代码以反斜杠为前缀。文字数字可以用100(表示整数),100.0(表示浮点值)或1.0e5(科学记数法)等形式编写。文字时间戳可以写成TIMESTAMP '2000-01-01 00:00:00'。文字间隔,用于时间算法,可以这样写INTERVAL '1' HOURINTERVAL '1 02:03' DAY TO MINUTEINTERVAL '1-2' YEAR TO MONTH,等等。

Druid SQL支持具有以下结构的SELECT查询:

[ EXPLAIN PLAN FOR ]
[ WITH tableName [ ( column1, column2, ... ) ] AS ( query ) ]
SELECT [ ALL | DISTINCT ] { * | exprs }
FROM table
[ WHERE expr ]
[ GROUP BY exprs ]
[ HAVING expr ]
[ ORDER BY expr [ ASC | DESC ], expr [ ASC | DESC ], ... ]
[ LIMIT limit ]
[ UNION ALL <another query> ]

到任何一个数据源德,像FROM子句是指druid.foo,一个INFORMATION_SCHEMA表,子查询,或共表表达在所提供的WITH子句。如果FROM子句引用子查询或common-table-expression,并且两个查询级别都是聚合,并且它们无法组合到单个聚合级别,则整个查询将作为嵌套GroupBy执行。

WHERE子句引用FROM表中的列,并将转换为本机过滤器。WHERE子句也可以引用子查询,例如WHERE col1 IN (SELECT foo FROM ...)。像这样的查询作为半连接执行,如下所述。

GROUP BY子句引用FROM表中的列。使用GROUP BY,DISTINCT或任何聚合函数将使用Druid的三种本机聚合查询类型之一触发聚合查询。GROUP BY可以引用表达式或select子句序号位置(比如GROUP BY 2按第二个选定列分组)。

HAVING子句引用执行GROUP BY后出现的列。它可用于过滤分组表达式或聚合值。它只能与GROUP BY一起使用。

ORDER BY子句引用执行GROUP BY后出现的列。它可用于根据分组表达式或聚合值对结果进行排序。ORDER BY可以引用表达式或select子句序号位置(比如ORDER BY 2按第二个选定列排序)。对于非聚合查询,ORDER BY只能按__time列排序。对于聚合查询,ORDER BY可以按任何列排序。

LIMIT子句可用于限制返回的行数。它可以与任何查询类型一起使用。它被推送到使用本机TopN查询类型而不是本机GroupBy查询类型运行的查询的数据进程。未来版本的Druid也将支持使用本机GroupBy查询类型下推限制。如果您注意到添加限制并未对性能产生太大影响,那么德鲁伊可能不会降低您的查询限制。

“UNION ALL”运算符可用于将多个查询融合在一起。它们的结果将被连接,每个查询将分开运行,背靠背(不是并行)。德鲁伊目前不支持“UNION”而没有“ALL”。

将“EXPLAIN PLAN FOR”添加到任何查询的开头,以查看它将如何作为本机Druid查询运行。在这种情况下,查询实际上不会被执行。

聚合功能

聚合函数可以出现在任何查询的SELECT子句中。可以使用类似语法过滤任何聚合器 AGG(expr) FILTER(WHERE whereExpr)。过滤的聚合器仅聚合与其过滤器匹配的行。同一SQL查询中的两个聚合器可能具有不同的筛选器。

只有COUNT聚合可以接受DISTINCT。

功能笔记
COUNT(*)计算行数。
COUNT(DISTINCT expr)计算expr的不同值,可以是string,numeric或hyperUnique。默认情况下,这是近似值,使用HyperLogLog的变体。要获得准确的计数,请将“useApproximateCountDistinct”设置为“false”。如果这样做,expr必须是字符串或数字,因为使用hyperUnique列无法进行精确计数。另见APPROX_COUNT_DISTINCT(expr)。在精确模式下,每个查询只允许一个不同的计数。
SUM(expr)求和数。
MIN(expr)采用最少的数字。
MAX(expr)取最大数字。
AVG(expr)平均数。
APPROX_COUNT_DISTINCT(expr)计算expr的不同值,可以是常规列或hyperUnique列。无论“useApproximateCountDistinct”的值如何,这始终是近似值。另见COUNT(DISTINCT expr)
APPROX_COUNT_DISTINCT_DS_HLL(expr, [lgK, tgtHllType])计算expr的不同值,可以是常规列或HLL草图列。的lgKtgtHllType参数的HLL草图文档中描述。无论“useApproximateCountDistinct”的值如何,这始终是近似值。另见COUNT(DISTINCT expr)。该DataSketches扩展必须加载使用此功能。
APPROX_COUNT_DISTINCT_DS_THETA(expr, [size])计算expr的不同值,可以是常规列或Theta sketch列。该size参数在Theta sketch文档中描述。无论“useApproximateCountDistinct”的值如何,这始终是近似值。另见COUNT(DISTINCT expr)。该DataSketches扩展必须加载使用此功能。
APPROX_QUANTILE(expr, probability, [resolution])计算numeric或approxHistogram exprs的近似分位数。“概率”应该在0和1之间(不包括)。“分辨率”是用于计算的质心数。分辨率越高,结果越精确,但开销也越高。如果未提供,则默认分辨率为50. 必须加载近似直方图扩展才能使用此功能。
APPROX_QUANTILE_DS(expr, probability, [k])计算数值或Quantiles草图 exprs的近似分位数。“概率”应该在0和1之间(不包括)。该k参数在Quantiles草图文档中描述。该DataSketches扩展必须加载使用此功能。
APPROX_QUANTILE_FIXED_BUCKETS(expr, probability, numBuckets, lowerLimit, upperLimit, [outlierHandlingMode])计算数字或固定桶直方图 exprs的近似分位数。“概率”应该在0和1之间(不包括)。的numBucketslowerLimitupperLimit,和outlierHandlingMode参数在固定桶中描述直方图文档。在近似直方图扩展必须加载使用此功能。
BLOOM_FILTER(expr, numEntries)根据生成的值计算布隆过滤器,在假定正比率增加之前expr使用numEntries最大数量的不同值。有关其他详细信息,请参阅bloom filter扩展文档

数字函数

数字函数将返回64位整数或64位浮点数,具体取决于它们的输入。

功能笔记
ABS(expr)绝对值。
CEIL(expr)天花板。
EXP(expr)e到expr的力量。
FLOOR(expr)地板。
LN(expr)对数(基数e)。
LOG10(expr)对数(基数10)。
POWER(expr, power)expr to a power。
SQRT(expr)平方根。
TRUNCATE(expr[, digits])将expr截断为特定的小数位数。如果数字为负数,则会截断小数点左侧的许多位置。如果未指定,数字默认为零。
TRUNC(expr[, digits])同义词TRUNCATE
x + y加成。
x - y减法。
x * y乘法。
x / y师。
MOD(x, y)模数(x的余数除以y)。

字符串函数

字符串函数接受字符串,并返回适合该函数的类型。

功能笔记
`x \\
CONCAT(expr, expr...)Concats表达式列表。
TEXTCAT(expr, expr)CONCAT的两个参数版本。
LENGTH(expr)以UTF-16代码单位表示的expr长度。
CHAR_LENGTH(expr)同义词LENGTH
CHARACTER_LENGTH(expr)同义词LENGTH
STRLEN(expr)同义词LENGTH
LOOKUP(expr, lookupName)在已注册的查询时查找表中查找 expr 。
LOWER(expr)全部以小写形式返回expr。
POSITION(needle IN haystack [FROM fromIndex])返回haystack中针的索引,索引从1开始。搜索将从fromIndex开始,如果未指定fromIndex,则为1。如果未找到针,则返回0。
REGEXP_EXTRACT(expr, pattern, [index])应用正则表达式模式并提取捕获组,如果没有匹配则为null。如果index未指定或为零,则返回与模式匹配的子字符串。
REPLACE(expr, pattern, replacement)用expr中的替换替换模式,并返回结果。
STRPOS(haystack, needle)返回haystack中针的索引,索引从1开始。如果未找到针,则返回0。
SUBSTRING(expr, index, [length])返回expr的子字符串,从index开始,具有最大长度,均以UTF-16代码单位测量。
SUBSTR(expr, index, [length])SUBSTRING的同义词。
`TRIM([BOTH \领导 \
BTRIM(expr[, chars])替代形式TRIM(BOTH <chars> FROM <expr>)。
LTRIM(expr[, chars])替代形式TRIM(LEADING <chars> FROM <expr>)。
RTRIM(expr[, chars])替代形式TRIM(TRAILING <chars> FROM <expr>)。
UPPER(expr)以全部大写形式返回expr。

时间功能

时间函数可以与Druid __time列一起使用,任何列通过使用MILLIS_TO_TIMESTAMP函数存储毫秒时间戳,或者通过使用函数存储字符串时间戳的任何列TIME_PARSE 。默认情况下,时间操作使用UTC时区。您可以通过将连接上下文参数“sqlTimeZone”设置为另一个时区的名称(如“America / Los_Angeles”)或更改为“-08:00”之类的偏移来更改时区。如果需要在同一查询中混合多个时区,或者如果需要使用连接时区以外的时区,则某些功能还会将时区作为参数接受。这些参数始终优先于连接时区。

功能笔记
CURRENT_TIMESTAMP连接时区中的当前时间戳。
CURRENT_DATE连接时区中的当前日期。
DATE_TRUNC(<unit>, <timestamp_expr>)将时间戳缩小,将其作为新时间戳返回。单位可以是“毫秒”,“秒”,“分钟”,“小时”,“日”,“周”,“月”,“季度”,“年”,“十年”,“世纪”或“千禧年” ”。
TIME_FLOOR(<timestamp_expr>, <period>, [<origin>, [<timezone>]])将时间戳缩小,将其作为新时间戳返回。期间可以是任何ISO8601期间,如P3M(季度)或PT12H(半天)。时区(如果提供)应为时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。此功能类似FLOOR但更灵活。
TIME_SHIFT(<timestamp_expr>, <period>, <step>, [<timezone>])按时间段(步骤时间)移动时间戳,将其作为新时间戳返回。期间可以是任何ISO8601期间。步骤可能是否定的。时区(如果提供)应为时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。
TIME_EXTRACT(<timestamp_expr>, [<unit>, [<timezone>]])从expr中提取时间部分,将其作为数字返回。单位可以是EPOCH,SECOND,MINUTE,HOUR,DAY(日期),DOW(星期几),DOY(一年中的一天),WEEK(星期),MONTH(1到12),QUARTER(1通过4),或年。时区(如果提供)应为时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。此功能类似EXTRACT但更灵活。单位和时区必须是文字,必须提供引用,如TIME_EXTRACT(__time, 'HOUR')TIME_EXTRACT(__time, 'HOUR', 'America/Los_Angeles')
TIME_PARSE(<string_expr>, [<pattern>, [<timezone>]])使用给定的Joda DateTimeFormat模式将字符串解析为时间戳,或者2000-01-02T03:04:05Z如果未提供模式,则使用ISO8601(例如)。时区(如果提供)应为时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”,并将用作不包含时区偏移的字符串的时区。模式和时区必须是文字。无法解析为时间戳的字符串将返回NULL。
TIME_FORMAT(<timestamp_expr>, [<pattern>, [<timezone>]])将时间戳格式化为具有给定Joda DateTimeFormat模式的字符串,或者2000-01-02T03:04:05Z如果未提供模式,则将ISO8601(例如)格式化。时区(如果提供)应为时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。模式和时区必须是文字。
MILLIS_TO_TIMESTAMP(millis_expr)将自纪元以来的毫秒数转换为时间戳。
TIMESTAMP_TO_MILLIS(timestamp_expr)将时间戳转换为自纪元以来的毫秒数。
EXTRACT(<unit> FROM timestamp_expr)从expr中提取时间部分,将其作为数字返回。单位可以是EPOCH,SECOND,MINUTE,HOUR,DAY(日期),DOW(星期几),DOY(一年中的某一天),WEEK(一周中的一周),MONTH,QUARTER或YEAR。单位必须不加引用,如EXTRACT(HOUR FROM __time)
FLOOR(timestamp_expr TO <unit>)将时间戳缩小,将其作为新时间戳返回。单位可以是秒,分钟,小时,天,周,月,季或年。
CEIL(timestamp_expr TO <unit>)舍入时间戳,将其作为新时间戳返回。单位可以是秒,分钟,小时,天,周,月,季或年。
TIMESTAMPADD(<unit>, <count>, <timestamp>)相当于timestamp + count * INTERVAL '1' UNIT
`timestamp_expr {+ \- } `

比较运算符

功能笔记
x = y等于。
x <> y不,等于。
x > y比...更棒。
x >= y大于或等于。
x < y少于。
x <= y小于或等于。
x BETWEEN y AND z相当于x >= y AND x <= z
x NOT BETWEEN y AND z相当于x < y OR x > z
x LIKE pattern [ESCAPE esc]如果x匹配SQL LIKE模式(带有可选的转义),则为true。
x NOT LIKE pattern [ESCAPE esc]如果x与SQL LIKE模式(带有可选的转义)不匹配,则为True。
x IS NULL如果x为NULL或空字符串,则为True。
x IS NOT NULL如果x既不是NULL也不是空字符串,则为真。
x IS TRUE如果x为真,则为真。
x IS NOT TRUE如果x不为真,则为真。
x IS FALSE如果x为假,则为真。
x IS NOT FALSE如果x不为假,则为真。
x IN (values)如果x是列出的值之一,则为真。
x NOT IN (values)如果x不是列出的值之一,则为真。
x IN (subquery)如果子查询返回x,则返回true。有关Druid SQL如何处理的详细信息,请参阅上面的语法和执行IN (subquery)
x NOT IN (subquery)如果子查询未返回x,则为true。有关Druid SQL如何处理的详细信息,请参阅语法和执行IN (subquery)
x AND y布尔AND。
x OR y布尔OR。
NOT x布尔NOT。

其他功能

功能笔记
CAST(value AS TYPE)将值转换为其他类型。有关Druid SQL如何处理CAST的详细信息,请参阅数据类型和强制类型转换
CASE expr WHEN value1 THEN result1 \[ WHEN value2 THEN result2 ... \] \[ ELSE resultN \] END简单案例。
CASE WHEN boolean_expr1 THEN result1 \[ WHEN boolean_expr2 THEN result2 ... \] \[ ELSE resultN \] END搜索案例。
NULLIF(value1, value2)如果value1和value2匹配则返回NULL,否则返回value1。
COALESCE(value1, value2, ...)返回既不是NULL也不是空字符串的第一个值。
BLOOM_FILTER_TEST(<expr>, <serialized-filter>)如果值包含在base64序列化bloom过滤器中,则返回true。有关其他详细信息,请参阅bloom filter扩展文档

不支持的功能

Druid不支持所有SQL功能,包括:

  • OVER子句和分析函数,如LAGLEAD
  • JOIN子句,除了如上所述的半连接之外。
  • OFFSET条款。
  • DDL和DML。

此外,SQL语言不支持某些德鲁伊功能。一些不受支持的德鲁伊功能包括:

数据类型和强制转换

Druid本身支持五种基本列类型:“long”(64位符号int),“float”(32位浮点数),“double”(64位浮点数)“string”(UTF-8编码字符串)和“复杂” (对于更多异国情调的数据类型,如hyperUnique和approxHistogram列,全能)。时间戳(包括__time列)存储为long,其值为自1970年1月1日UTC以来的毫秒数。

在运行时,德鲁伊可能会为某些运算符(如SUM聚合器)将32位浮点数扩展为64位。反过来不会发生:64位浮点数不会缩小到32位。

Druid通常可以互换地处理NULL和空字符串,而不是根据SQL标准。因此,Druid SQL只对NULL有部分支持。例如,表达式col IS NULLcol = ''是等价的,如果双方将评估为true col包含一个空字符串。同样,如果是空字符串,表达式COALESCE(col1, col2)将返回。当聚合器计算所有行时, 聚合器将计算expr既不为空也不为空字符串的行数。Druid中的字符串列是NULLable。数字列不是NULL; 如果查询Druid数据源的所有段中不存在的数字列,则对于来自这些段的行,它将被视为零。col2col1COUNT(*)COUNT(expr)

对于数学运算,如果表达式中涉及的所有操作数都是整数,则Druid SQL将使用整数数学运算。否则,德鲁伊将切换到浮点数学。您可以通过将一个操作数强制转换为FLOAT来强制执行此操作。

下表描述了SQL类型在查询运行时期间如何映射到Druid类型。除了表中提到的异常之外,具有相同Druid运行时类型的两种SQL类型之间的转换将不起作用。两种具有不同Druid运行时类型的SQL类型之间的转换将在Druid中生成运行时强制转换。如果某个值无法正确转换为其他值CAST('foo' AS BIGINT),则运行时将替换默认值。转换为非可空类型的NULL值也将替换为默认值(例如,转换为数字的空值将转换为零)。

SQL类型德鲁伊运行时类型默认值笔记
CHAR'' 
VARCHAR''Druid STRING列报告为VARCHAR
DECIMAL0.0DECIMAL使用浮点数,而不是定点数学
浮动浮动0.0德鲁伊FLOAT柱报告为FLOAT
真实0.0 
0.0Druid DOUBLE列报告为DOUBLE
布尔false 
TINYINT0 
SMALLINT0 
整数0 
BIGINT0德鲁伊LONG列(除外__time)报告为BIGINT
TIMESTAMP0,意思是1970-01-01 00:00:00 UTC德鲁伊的__time专栏报道为TIMESTAMP。字符串和时间戳类型之间的转换假定标准SQL格式,例如2000-01-02 03:04:05不是 ISO8601格式。要处理其他格式,请使用其中一个时间函数
日期0,意思是1970-01-01将TIMESTAMP转换为DATE会将时间戳向下舍入到最近的一天。字符串和日期类型之间的转换假定标准SQL格式,例如2000-01-02。要处理其他格式,请使用其中一个时间函数
其他复杂没有可以代表各种德鲁伊列类型,如hyperUnique,approxHistogram等

查询执行

没有聚合的查询将使用德鲁伊的扫描选择本机查询类型。尽可能使用扫描,因为它通常比Select更高性能和更高效。但是,在一种情况下使用Select:当查询包含a时ORDER BY __time,因为Scan没有排序功能。

聚合查询(使用GROUP BY,DISTINCT或任何聚合函数)将使用Druid的三种本机聚合查询类型之一。两个(Timeseries和TopN)专门用于特定类型的聚合,而另一个(GroupBy)是通用的。

  • 时间序列用于GROUP BY FLOOR(__time TO <unit>)TIME_FLOOR(__time, period)没有其他分组表达式的查询,没有HAVING或LIMIT子句,没有嵌套,没有ORDER BY,或者按GROUP BY中的相同表达式排序的ORDER BY。它还将Timeseries用于具有聚合函数但没有GROUP BY的“总计”查询。此查询类型利用了德鲁伊段按时间排序的事实。

  • 默认情况下,TopN用于按单个表达式分组的查询,具有ORDER BY和LIMIT子句,没有HAVING子句,并且不嵌套。但是,在某些情况下,TopN查询类型将提供近似排名和结果; 如果要避免这种情况,请将“useApproximateTopN”设置为“false”。TopN结果始终在内存中计算。有关更多详细信息,请参阅TopN文档。

  • GroupBy用于所有其他聚合,包括任何嵌套聚合查询。Druid的GroupBy是一个传统的聚合引擎:它提供精确的结果和排名,并支持各种功能。如果可以,GroupBy会在内存中聚合,但如果没有足够的内存来完成查询,它可能会溢出到磁盘。如果您在GROUP BY子句中使用相同的表达式ORDER BY,或者根本没有ORDER BY,则结果将通过Broker从数据进程流回。如果您的查询具有ORDER BY引用未出现在GROUP BY子句中的表达式(如聚合函数),则Broker将在内存中实现结果列表,最多为LIMIT(如果有)。有关调整性能和内存使用的详细信息,请参阅GroupBy文档。

如果您的查询执行嵌套聚合(FROM子句中的聚合子查询),那么Druid将作为嵌套GroupBy执行它 。在嵌套的GroupBys中,最内层的聚合是分布式的,但除此之外的所有外部聚合都在查询Broker上本地发生。

包含WHERE子句的半连接查询col IN (SELECT expr FROM ...)是使用特殊进程执行的。Broker将首先将子查询转换为GroupBy以查找不同的值expr。然后,代理将子查询重写为文字过滤器,col IN (val1, val2, ...)并运行外部查询。配置参数druid.sql.planner.maxSemiJoinRowsInMemory控制将为此类计划实现的最大值数。

对于所有本机查询类型,__time列上的过滤器将尽可能地转换为顶级查询“间隔”,这允许Druid使用其全局时间索引来快速修剪必须扫描的数据集。此外,德鲁伊将使用每个数据流程的本地索引来进一步加速WHERE评估。这通常可以用于涉及对单列的引用和函数的布尔组合的过滤器,例如 WHERE col1 = 'a' AND col2 = 'b'但不是WHERE col1 = col2

近似算法

在某些情况下,德鲁伊SQL将使用近似算法:

  • COUNT(DISTINCT col)默认情况下,聚合函数使用HyperLogLog的变体, HyperLogLog是一种快速近似的不同计数算法。如果通过查询上下文或通过Broker配置将“useApproximateCountDistinct”设置为“false”,Druid SQL将切换到完全不同的计数。
  • 使用ORDER BY和LIMIT对单个列进行GROUP BY查询可以使用TopN引擎执行,该引擎使用近似算法。如果通过查询上下文或通过Broker配置将“useApproximateTopN”设置为“false”,Druid SQL将切换到精确的分组算法。
  • 无论配置如何,APPROX_COUNT_DISTINCT和APPROX_QUANTILE聚合函数始终使用近似算法。

客户端API

JSON over HTTP

您可以通过发布到端点使用JSON over HTTP进行Druid SQL查询/druid/v2/sql/。请求应该是带有“查询”字段的JSON对象,例如{"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar'"}

您可以使用curl从命令行发送SQL查询:

$ cat query.json
{"query":"SELECT COUNT(*) AS TheCount FROM data_source"}

$ curl -XPOST -H'Content-Type: application/json' http://BROKER:8082/druid/v2/sql/ -d @query.json
[{"TheCount":24433}]

您可以通过添加“上下文”映射来提供各种连接上下文参数,例如:

{
  "query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
  "context" : {
    "sqlTimeZone" : "America/Los_Angeles"
  }
}

通过查询系统表,可以通过HTTP API获得元数据。

回应

Druid SQL支持各种结果格式。您可以通过添加“resultFormat”参数来指定这些参数,例如:

{
  "query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
  "resultFormat" : "object"
}

支持的结果格式为:

格式描述内容类型
object默认情况下,JSON对象的JSON数组。每个对象的字段名称与SQL查询返回的列匹配,并以与SQL查询相同的顺序提供。应用程序/ JSON
arrayJSON数组的JSON数组。每个内部数组都按顺序具有与SQL查询返回的列匹配的元素。应用程序/ JSON
objectLines与“object”类似,但JSON对象由换行符分隔,而不是包装在JSON数组中。如果您没有对流式JSON解析器的准备访问权限,则可以更轻松地将整个响应集解析为流。为了能够检测截断的响应,此格式包括一个空行的预告片。纯文本/
arrayLines与“数组”类似,但JSON数组由换行符分隔,而不是包装在JSON数组中。如果您没有对流式JSON解析器的准备访问权限,则可以更轻松地将整个响应集解析为流。为了能够检测截断的响应,此格式包括一个空行的预告片。纯文本/
csv以逗号分隔的值,每行一行。单个字段值可以通过用双引号括起来转义。如果双引号出现在字段值中,它们将通过用双引号替换它们来转义""this""。为了能够检测截断的响应,此格式包括一个空行的预告片。文/ CSV

您还可以通过在请求中将“header”设置为true来请求标头,例如:

{
  "query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
  "resultFormat" : "arrayLines",
  "header" : true
}

在这种情况下,返回的第一个结果将是标题。对于csvarrayarrayLines格式,标题将是列名的列表。对于objectobjectLines格式,标题将是一个对象,其中键是列名,值为null。

发送响应主体之前发生的错误将以JSON报告,其中包含HTTP 500状态代码,格式与本机德鲁伊查询错误相同。如果在发送响应正文时发生错误,那么更改HTTP状态代码或报告JSON错误为时已晚,因此响应将简单地在中途结束,并且德鲁伊服务器将记录错误处理您的请求。

作为调用者,正确处理响应截断非常重要。这对于“对象”和“数组”格式很容易,因为截断的响应将是无效的JSON。对于面向行的格式,您应该检查它们都包含的预告片:结果集末尾的一个空行。如果通过JSON解析错误或缺少尾随换行检测到截断的响应,则应该假定响应由于错误而未完全传递。

JDBC

您可以使用Avatica JDBC驱动程序进行Druid SQL查询。下载Avatica客户端jar后,将其添加到类路径并使用连接字符串jdbc:avatica:remote:url=http://BROKER:8082/druid/v2/sql/avatica/

示例代码:

// Connect to /druid/v2/sql/avatica/ on your Broker.
String url = "jdbc:avatica:remote:url=http://localhost:8082/druid/v2/sql/avatica/";

// Set any connection context parameters you need here (see "Connection context" below).
// Or leave empty for default behavior.
Properties connectionProperties = new Properties();

try (Connection connection = DriverManager.getConnection(url, connectionProperties)) {
  try (
      final Statement statement = connection.createStatement();
      final ResultSet resultSet = statement.executeQuery(query)
  ) {
    while (resultSet.next()) {
      // Do something
    }
  }
}

可以使用connection.getMetaData()或通过查询 “INFORMATION_SCHEMA”表在JDBC上使用表元数据。参数化查询(使用?或其他占位符)无法正常工作,因此请避免使用这些查询。

连接粘性

Druid的JDBC服务器不共享Brokers之间的连接状态。这意味着如果您使用JDBC并拥有多个Druid Broker,则应该连接到特定Broker,或者使用启用了粘性会话的负载均衡器。德鲁伊路由器进程在平衡JDBC请求时提供连接粘性,并且即使使用普通的非粘性负载均衡器也可用于实现必要的粘性。有关更多详细信息,请参阅 路由器文档。

请注意,非JDBC JSON over HTTP API是无状态的,不需要粘性。

连接上下文

Druid SQL支持在客户端上设置连接参数。下表中的参数会影响SQL计划。您提供的所有其他上下文参数将附加到Druid查询,并可能影响它们的运行方式。有关可能选项的详细信息,请参阅 查询上下文

请注意,要为SQL查询指定唯一标识符,请使用sqlQueryId而不是queryIdqueryIdSQL请求的设置无效,SQL下的所有本机查询都将使用自动生成的queryId。

连接上下文可以指定为JDBC连接属性,也可以指定为JSON API中的“上下文”对象。

参数描述默认值
sqlQueryId为此SQL查询提供的唯一标识符。对于HTTP客户端,它将在X-Druid-SQL-Query-Id标头中返回。自动生成
sqlTimeZone设置此连接的时区,这将影响时间函数和时间戳文字的行为方式。应该是时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。Broker上的druid.sql.planner.sqlTimeZone(默认值:UTC)
useApproximateCountDistinct是否使用近似基数算法COUNT(DISTINCT foo)Broker上的druid.sql.planner.useApproximateCountDistinct(默认值:true)
useApproximateTopN当SQL查询可以表达时,是否使用近似TopN查询。如果为false,则将使用确切的GroupBy查询Broker上的druid.sql.planner.useApproximateTopN(默认值:true)
useFallback当它们无法表达为德鲁伊查询时是否评估Broker上的操作。建议不要将此选项用于生产,因为它可以生成不可伸缩的查询计划。如果为false,则无法转换为Druid查询的SQL查询将失败。Broker上的druid.sql.planner.useFallback(默认值:false)

检索元数据

Druid Brokers从集群中加载的段中推断每个dataSource的表和列元数据,并使用它来计划SQL查询。此元数据在Broker启动时缓存,并通过SegmentMetadata查询在后台定期更新 。后台元数据刷新由进入和退出群集的段触发,也可以通过配置进行限制。

德鲁伊通过特殊的系统表公开系统信息。有两种这样的模式:信息模式和系统模式。信息模式提供有关表和列类型的详细信息。“sys”架构提供有关德鲁伊内部的信息,如段/任务/服务器。

信息模式

您可以使用JDBC connection.getMetaData()或通过下面描述的INFORMATION_SCHEMA表通过JDBC访问表和列元数据。例如,要检索Druid数据源“foo”的元数据,请使用以下查询:

SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'druid' AND TABLE_NAME = 'foo'

SCHEMATA表

笔记
CATALOG_NAME没用过
SCHEMA_NAME 
SCHEMA_OWNER没用过
DEFAULT_CHARACTER_SET_CATALOG没用过
DEFAULT_CHARACTER_SET_SCHEMA没用过
DEFAULT_CHARACTER_SET_NAME没用过
SQL_PATH没用过

表格表

笔记
TABLE_CATALOG没用过
TABLE_SCHEMA 
TABLE_NAME 
TABLE_TYPE“TABLE”或“SYSTEM_TABLE”

COLUMNS表

笔记
TABLE_CATALOG没用过
TABLE_SCHEMA 
TABLE_NAME 
COLUMN_NAME 
ORDINAL_POSITION 
COLUMN_DEFAULT没用过
IS_NULLABLE 
数据类型 
CHARACTER_MAXIMUM_LENGTH没用过
CHARACTER_OCTET_LENGTH没用过
NUMERIC_PRECISION 
NUMERIC_PRECISION_RADIX 
NUMERIC_SCALE 
DATETIME_PRECISION 
CHARACTER_SET_NAME 
COLLATION_NAME 
JDBC_TYPE输入java.sql.Types中的代码(德鲁伊扩展)

系统模式

“sys”模式提供了对德鲁伊段,服务器和任务的可见性。

SEGMENTS表

细分表提供了所有德鲁伊细分的细节,无论它们是否已发布。

警告

请注意,段可以由多个流提取任务或历史进程提供服务,在这种情况下,它将具有多个副本。当由多个摄取任务提供服务时,这些副本彼此弱相互一致,直到一个段最终由历史服务,此时该段是不可变的。Broker更喜欢通过摄取任务从Historical查询段。但是,如果一个片段有多个实时复制品,例如。kafka索引任务,并且一个任务比其他任务慢,那么sys.segments查询结果可以在任务持续时间内变化,因为Broker只查询其中一个摄取任务,并且不会保证选择相同的任务每次。所述num_rows段表中的列可以在此期间有不一致的值。有空位与流提取任务不一致的问题

笔记
SEGMENT_ID唯一段标识符
数据源数据源的名称
开始间隔开始时间(ISO 8601格式)
结束间隔结束时间(ISO 8601格式)
尺寸段的大小(以字节为单位)
版本字符串(通常是与首次启动段集时对应的ISO8601时间戳)。更高版本意味着最近创建的细分市场。版本比较基于字符串比较。
partition_num分区号(一个整数,在数据源中唯一+区间+版本;可能不一定是连续的)
num_replicas当前正在提供的此细分受众群的副本数
NUM_ROWS当前段中的行数,如果在查询时未向Broker发送,则此值可以为null
is_publishedBoolean表示为long类型,其中1 = true,0 = false。1表示此段已发布到元数据存储
is_availableBoolean表示为long类型,其中1 = true,0 = false。1如果此段目前由任何服务器提供(历史或实时)
is_realtimeBoolean表示为long类型,其中1 = true,0 = false。如果此段在任何类型的实时任务中提供,则为1
有效载荷JSON序列化数据段有效负载

例如,要检索数据源“wikipedia”的所有段,请使用以下查询:

SELECT * FROM sys.segments WHERE datasource = 'wikipedia'

另一个检索每个数据源的段total_size,avg_size,avg_num_rows和num_segments的示例:

SELECT
    datasource,
    SUM("size") AS total_size,
    CASE WHEN SUM("size") = 0 THEN 0 ELSE SUM("size") / (COUNT(*) FILTER(WHERE "size" > 0)) END AS avg_size,
    CASE WHEN SUM(num_rows) = 0 THEN 0 ELSE SUM("num_rows") / (COUNT(*) FILTER(WHERE num_rows > 0)) END AS avg_num_rows,
    COUNT(*) AS num_segments
FROM sys.segments
GROUP BY 1
ORDER BY 2 DESC

SERVERS表

服务器表列出了所有数据服务器(承载段的任何服务器)。它包括历史和Peons。

笔记
服务器表单host:port中的服务器名称
主办服务器的主机名
plaintext_port服务器的不安全端口,如果禁用明文流量,则为-1
tls_port服务器的TLS端口,如果禁用TLS,则为-1
SERVER_TYPE德鲁伊服务类型。可能的值包括:Historical,realtime和indexer_executor(Peon)。
一线分发层见druid.server.tier
目前的规模此服务器上的当前段大小(以字节为单位)
MAX_SIZE此服务器建议分配给段的最大大小(以字节为单位),请参阅druid.server.maxSize

要检索有关所有服务器的信息,请使用以下查询:

SELECT * FROM sys.servers;

SERVER_SEGMENTS表

SERVER_SEGMENTS用于将服务器与段表连接

笔记
服务器格式为host的服务器名称:port(服务器表的主键)
SEGMENT_ID段标识符(段表的主键)

“服务器”和“段”之间的连接可用于查询特定数据源的段数,按服务器,示例查询分组:

SELECT count(segments.segment_id) as num_segments from sys.segments as segments 
INNER JOIN sys.server_segments as server_segments 
ON segments.segment_id  = server_segments.segment_id 
INNER JOIN sys.servers as servers 
ON servers.server = server_segments.server
WHERE segments.datasource = 'wikipedia' 
GROUP BY servers.server;

任务表

tasks表提供有关活动和最近完成的索引任务的信息。有关更多信息,请查看摄取任务

笔记
TASK_ID唯一任务标识符
类型任务类型,例如此值是索引任务的“索引”。请参阅任务 - 概述
数据源正在编制索引的数据源名称
CREATED_TIMEISO8601格式的时间戳,对应于创建摄取任务的时间。请注意,此值将填充已完成和正在等待的任务。对于运行和挂起任务,此值设置为1970-01-01T00:00:00Z
queue_insertion_timeISO8601格式的时间戳,对应于将此任务添加到Overlord上的队列时
状态任务的状态可以是RUNNING,FAILED,SUCCESS
runner_status已完成任务的运行者状态为NONE,对于正在进行的任务,可以是RUNNING,WAITING,PENDING
持续时间完成任务所需的时间(以毫秒为单位),此值仅适用于已完成的任务
地点运行此任务的服务器名称,格式为host:port,此信息仅适用于RUNNING任务
主办正在运行任务的服务器的主机名
plaintext_port服务器的不安全端口,如果禁用明文流量,则为-1
tls_port服务器的TLS端口,如果禁用TLS,则为-1
ERROR_MSGFAILED任务时的详细错误消息

例如,要检索按状态筛选的任务信息,请使用查询

SELECT * FROM sys.tasks WHERE status='FAILED';

请注意,sys表可能不支持所有Druid SQL函数。

服务器配置

通过Broker上的以下属性配置Druid SQL服务器。

属性描述默认
druid.sql.enable是否要启用SQL,包括后台元数据获取。如果为false,则会覆盖所有其他与SQL相关的属性,并完全禁用SQL元数据,服务和计划。
druid.sql.avatica.enable是否启用JDBC查询/druid/v2/sql/avatica/真正
druid.sql.avatica.maxConnectionsAvatica服务器的最大打开连接数。这些不是HTTP连接,而是可以跨越多个HTTP连接的逻辑客户端连接。25
druid.sql.avatica.maxRowsPerFrame单个JDBC框架中要返回的最大行数。将此属性设置为-1表示不应应用行限制。客户端可以选择在其请求中指定行限制; 如果客户端指定行限制,则将使用客户端提供的限制的较小值maxRowsPerFrame5000
druid.sql.avatica.maxStatementsPerConnection每个Avatica客户端连接的最大同时打开语句数。4
druid.sql.avatica.connectionIdleTimeoutAvatica客户端连接空闲超时。PT5M
druid.sql.http.enable是否通过HTTP查询启用JSON/druid/v2/sql/真正
druid.sql.planner.maxQueryCount要发出的最大查询数,包括嵌套查询。设置为1表示禁用子查询,或设置为0表示无限制。8
druid.sql.planner.maxSemiJoinRowsInMemory内存中用于执行两阶段半连接查询的最大行数,例如SELECT * FROM Employee WHERE DeptName IN (SELECT DeptName FROM Dept)100000
druid.sql.planner.maxTopNLimitTopN查询的最大阈值。相反,将计划更高的限制作为GroupBy查询100000
druid.sql.planner.metadataRefreshPeriod节流元数据刷新。PT1M
druid.sql.planner.selectThreshold选择查询的页面大小阈值。对于较大的结果集的选择查询将使用分页背靠背发出。1000
druid.sql.planner.useApproximateCountDistinct是否使用近似基数算法COUNT(DISTINCT foo)真正
druid.sql.planner.useApproximateTopN当SQL查询可以表达时,是否使用近似TopN查询。如果为false,则将使用确切的GroupBy查询真正
druid.sql.planner.useFallback当它们无法表达为德鲁伊查询时是否评估Broker上的操作。建议不要将此选项用于生产,因为它可以生成不可伸缩的查询计划。如果为false,则无法转换为Druid查询的SQL查询将失败。
druid.sql.planner.requireTimeCondition是否要求SQL在__time列上具有过滤条件,以便所有生成的本机查询都具有用户指定的间隔。如果为true,则所有在__time列上没有过滤条件的查询都将失败
druid.sql.planner.sqlTimeZone设置服务器的默认时区,这将影响时间函数和时间戳文字的行为方式。应该是时区名称,如“America / Los_Angeles”或偏移量,如“-08:00”。世界标准时间
druid.sql.planner.metadataSegmentCacheEnable是否在代理中保留已发布段的缓存。如果为true,则代理在后台轮询协调器以从元数据存储中获取段并维护本地缓存。如果为false,则当代理需要发布段信息时,将调用协调器的REST api。
druid.sql.planner.metadataSegmentPollPeriod如果druid.sql.planner.metadataSegmentCacheEnable设置为true ,多长时间轮询协调器以查找已发布的段列表。轮询周期以毫秒为单位。60000

SQL指标

Broker将为SQL发出以下指标。

描述外形尺寸正常值
sqlQuery/time完成SQL所需的毫秒数。id,nativeQueryIds,dataSource,remoteAddress,success。<1s
sqlQuery/bytesSQL响应中返回的字节数。id,nativeQueryIds,dataSource,remoteAddress,success。 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值