SQL查询
概述
SQL查询是Druid内置的SQL层,是基于json的查询语言的替代方式,SQL查询在查询节点上转换成本地的查询,然后传递给数据流程,除了在查询节点上翻译SQL的性能开销之外,与Druid提供的json查询没有其他的性能损失。
一、查询语法
[1] 书写使用说明
每个Druid数据源在操作模式中显示为一个表。这也是默认的模式,所以Druid数据源有两种引用方式: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' HOUR,INTERVAL '1 02:03' DAY TO MINUTE,INTERVAL '1-2' YEAR TO MONTH,等等。
[2] 支持查询
[ 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> ]
[3] 使用说明
FROM子句引用Druid数据源,例如Druid.foo,INFORMATION_SCHEMA表,子查询或WITH子句中提供的common-table-expression。如果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按第二个select 列分组)。
HAVING子句引用执行GROUP BY后出现的列。它可用于过滤分组表达式或聚合值。它只能与GROUP BY一起使用。
ORDER BY子句引用执行GROUP BY后出现的列。它可用于根据分组表达式或汇总值对结果进行排序。ORDER BY可以引用表达式或select子句的序数位置(类似于ORDER BY 2第二个选定列的顺序)。对于非聚合查询,ORDER BY只能按__time列排序。对于聚合查询,ORDER BY可以按任何列排序。
LIMIT子句可用于限制返回的行数。它可以与任何查询类型一起使用。
" UNION ALL"运算符可用于将多个查询融合在一起。它们的结果将被串联起来,并且每个查询都连续单独运行(非并行)。如果没有" ALL",则Druid当前不支持" UNION"。
在任何查询的开头添加" EXPLAIN PLAN FOR",以查看SQL的查询计划。在这种情况下,查询将不会实际执行。
二、数据类型和类型转换(Data types and casts)
Druid支持五种基本列类型
- long(64位带符号的int)
- float(32位浮点)
- double(64位浮点)
- string(UTF-8编码的字符串和字符串数组)
- complex(全部捕获以获取更多特殊数据类型)
时间戳列被当做long,Druid中的时间戳不携带任何时区信息,而仅携带有关它们所代表的确切时间的信息
空处理模式,默认情况下,Druid会交替处理NULL和空字符串,而不是根据SQL标准。因此,在这种模式下,Druid SQL仅部分支持NULL。例如,表达式col IS NULL和col = ''是等效的,并且如果col包含空字符串,则两者都将得出true 。同样,如果为空字符串,则表达式COALESCE(col1, col2)将返回。当聚合器计算所有行时, 聚合器将计算expr既不为null也不为空字符串的行数。Druid中的字符串列可为NULL。数字列不为空;如果查询的Druid数据源的所有段中都不存在数字列,则这些段中的行将被视为零
对于数学运算,如果表达式中涉及的所有操作数均为整数,则Druid SQL将使用整数计算。否则,Druid将切换到浮点计算。您可以通过将其中一个操作数强制转换为FLOAT来强制执行此操作。在运行时,对于某些运算符,例如SUM聚合器,Druid可以将32位浮点数扩展到64位。
如果Druid.generic.useDefaultValueForNull将其设置为false,则在索引编制时,将以允许区分字符串列的空字符串和NULL值的方式存储数据,并允许为数字列存储NULL值。通常,Druid SQL将在此模式下更正常地运行,并且SQL优化器将在此模式下运行最佳。
Druid 多值字符串将按类型显示在表模式中,并且可以在表达式中与之交互。此外,可以ARRAY通过一些特殊的多值运算符将它们视为"类似"。针对多值字符串维的表达式会将表达式应用于行的所有值,但是需要注意的是,这些多值字符串列上的聚合将遵循本机Druid多值聚合行为,这等效UNNEST于许多方言。
下表描述了在查询运行期间SQL类型如何映射到Druid类型。具有相同Druid运行时类型的两种SQL,类型之间的强制转换将无效,除了表中指出的异常。具有不同Druid运行时类型的两种SQL类型之间的强制转换将在Druid中生成一个运行时强制转换。如果一个值不能正确地转换为另一个值,如中CAST('foo' AS BIGINT)所述,运行时将替换为默认值。强制转换为非空类型的NULL值也将替换为默认值(例如,强制转换为数字的null将转换为零)。
SQL类型 | Druid运行类型 | 默认值 | 注意 |
---|---|---|---|
CHAR | STRING | '' | |
VARCHAR | STRING | '' | Druid STRING列为VARCHAR |
DECIMAL | DOUBLE | 0.0 | DECIMAL使用浮点数,而不是定点数 |
FLOAT | FLOAT | 0.0 | Druid FLOAT列为FLOAT |
REAL | DOUBLE | 0.0 | |
DOUBLE | DOUBLE | 0.0 | Druid DOUBLE列为DOUBLE |
BOOLEAN | LONG | false | |
TINYINT | LONG | 0 | |
SMALLINT | LONG | 0 | |
INTEGER | LONG | 0 | |
BIGINT | LONG | 0 | Druid LONG列(除外__time)为BIGINT |
TIMESTAMP | LONG | 0, 意思是 1970-01-01 00:00:00 UTC | Druid的__time专栏报告为TIMESTAMP。字符串和时间戳类型之间的强制转换采用标准SQL格式,例如2000-01-02 03:04:05,不是 ISO8601格式。 |
DATE | LONG | 0, 意思是 1970-01-01 | 将TIMESTAMP转换为DATE会将时间戳四舍五入到最近的日期。字符串和日期类型之间的强制转换采用标准SQL格式,例如2000-01-02。 |
OTHER | COMPLEX | none | 可以表示各种Druid列类型,例如hyperUnique,roxHistogram等 |
三、内置功能(Built-in functions)
[1] 聚合函数
聚合函数可以出现在任何查询的SELECT子句中。任何聚合器都可以使用语法进行过滤 AGG(expr) FILTER(WHERE whereExpr)。过滤的聚合器只会聚合与其过滤器匹配的行。同一SQL查询中的两个聚合器可能具有不同的过滤器。
功能 | 描述 |
---|---|
COUNT(*) | 计算行数。 |
COUNT(DISTINCT expr) | 计算expr的不同值,这些值可以是字符串,数字或hyperUnique。默认情况下,这是近似值。要获得准确的计数,请将" useroximateDistinct"设置为" false"。如果这样做,expr必须为字符串或数字,因为使用hyperUnique列无法进行精确计数。另请参阅APPROX_COUNT_DISTINCT(expr)。在精确模式下,每个查询只允许一个不同的计数。 |
SUM(expr) | 对数字求和。 |
MIN(expr) | 取最小值。 |
MAX(expr) | 取最大值。 |
AVG(expr) | 平均值。 |
APPROX_COUNT_DISTINCT(expr) | 计算expr的不同值,这些值可以是常规列或hyperUnique列。无论" useroximateCountDistinct"的值如何,该值始终是近似值。这使用了Druid内置的"基数"或" hyperUnique"聚合器。 |
APPROX_COUNT_DISTINCT_DS_HLL(expr, [lgK, tgtHllType]) | 计算expr的不同值,这些值可以是常规列或HLL草图列。无论" useroximateCountDistinct"的值如何,该值始终是近似值。另请参阅COUNT(DISTINCT expr)。使用参函数需要添加DataSketches扩展。 |
APPROX_COUNT_DISTINCT_DS_THETA(expr, [size]) | 计算expr的不同值,这些值可以是常规列或Theta草图列。无论" useroximateCountDistinct"的值如何,该值始终是近似值。另请参阅COUNT(DISTINCT expr)。使用参函数需要添加DataSketches扩展。 |
DS_HLL(expr, [lgK, tgtHllType]) | 根据expr的值创建HLL草图列,该值可以是常规列或包含HLL草图的列。使用参函数需要添加DataSketches扩展。 |
DS_THETA(expr, [size]) | 在expr的值上创建Theta草图,该值可以是常规列或包含Theta草图的列。使用参函数需要添加DataSketches扩展。 |
APPROX_QUANTILE(expr, probability, [resolution]) | 根据数值或近似直方图表达式计算近似分位数。"概率"应在0到1(不包括)之间。"分辨率"是用于计算的质心数。较高的分辨率将提供更精确的结果,但也将具有较高的开销。如果未提供,则默认分辨率为50。使用参函数需要添加近似直方图扩展。 |
APPROX_QUANTILE_DS(expr, probability, [k]) | 在数字或分位数草图表达式上计算近似分位数。"概率"应在0到1(不包括)之间。使用参函数需要添加DataSketches扩展。 |
APPROX_QUANTILE_FIXED_BUCKETS(expr, probability, numBuckets, lowerLimit, upperLimit, [outlierHandlingMode]) | 在数字或固定存储桶直方图表达式上计算近似分位数。"概率"应在0到1(不包括)之间。使用参函数需要添加近似直方图扩展。 |
DS_QUANTILES_SKETCH(expr, [k]) | 在expr的值上创建分位数草图,该值可以是常规列或包含分位数草图的列。使用参函数需要添加DataSketches扩展。 |
BLOOM_FILTER(expr, numEntries) | 根据由产生的值,在误报率增加之前expr,使用numEntries最大数量的不同值来计算布隆过滤器。 |
TDIGEST_QUANTILE(expr, quantileFraction, [compression]) | 在由expr分位数产生的值上构建T-摘要草图,并返回分位数的值。压缩参数(默认值100)确定草图的精度和大小。更高的压缩率意味着更高的精度,但更多的空间可以存储草图。 |
TDIGEST_GENERATE_SKETCH(expr, [compression]) | 根据由产生的值构建T-摘要草图expr。压缩参数(默认值100)决定草图的精度和大小。较高的压缩率意味着较高的精度,但存储草图的空间更大。 |
VAR_POP(expr) | 计算expr总体的方差。 |
VAR_SAMP(expr) | 计算expr样本的方差。 |
VARIANCE(expr) | 计算expr样本的方差。 |
STDDEV_POP(expr) | 计算expr总体的标准偏差。 |
STDDEV_SAMP(expr) | 计算expr样本的标准偏差。 |
STDDEV(expr) | 计算expr样本的标准偏差。 |
EARLIEST(expr) | 返回的最早值expr,该值必须为数字。如果expr来自与timestamp列的关系(例如Druid数据源),则"最早"是最先遇到的值,同时汇总所有值的最小总时间戳。如果expr不是来自与时间戳的关系,那么它仅仅是遇到的第一个值。 |
EARLIEST(expr, maxBytesPerString) | 像EARLIEST(expr),但用于字符串。该maxBytesPerString参数确定每个字符串要分配多少聚合空间。超过此限制的字符串将被截断。此参数应设置得尽可能低,因为高值将导致内存浪费。 |
LATEST(expr) | 返回的最新值expr,该值必须为数字。如果expr来自与timestamp列的关系(例如Druid数据源),则" latest"是最后一次遇到的值,其中汇总了所有值的最大总时间戳。如果expr不是来自带有时间戳的关系,则它仅仅是遇到的最后一个值。 |
LATEST(expr, maxBytesPerString) | 像LATEST(expr),但用于字符串。该maxBytesPerString参数确定每个字符串要分配多少聚合空间。超过此限制的字符串将被截断。此参数应设置得尽可能低,因为高值将导致内存浪费。 |
[2] 数值函数
数值函数将返回64位整数或64位浮点数,具体取决于它们的输入。
功能 | 描述 |
---|---|
ABS(expr) | 绝对值。 |
CEIL(expr) | 向上规整。 |
EXP(expr) | 科学计数。 |
FLOOR(expr) | 向下规整。 |
LN(expr) | 对数(以e为底)。 |
LOG10(expr) | 对数(以10为底)。 |
POWER(expr, power) | N次方。 |
SQRT(expr) | 平方根。 |
TRUNCATE(expr[, digits]) | 将expr截断为特定数目的十进制数字。如果数字为负数,则这会将小数点左边的很多位截断。如果未指定,则数字默认为零。 |
TRUNC(expr[, digits]) | 与TRUNCATE类似。 |
ROUND(expr[, digits]) | ROUND(x, y)将返回四舍五入到小数点,y的x的值。x可以是整数或浮点数,而y必须是整数。返回值的类型由x指定。如果省略,则y默认为0。当y为负数时,x在y小数点的左侧舍入。 |
x + y | 相加。 |
x - y | 相减。 |
x * y | 相乘。 |
x / y | 相除。 |
MOD(x, y) | 取模(x的余数除以y)。 |
SIN(expr) | expr的三角正弦。 |
COS(expr) | expr的三角余弦。 |
TAN(expr) | expr的三角正切。 |
COT(expr) | expr的三角余切。 |
ASIN(expr) | expr的反正弦。 |
ACOS(expr) | expr的反余弦值。 |
ATAN(expr) | expr的反正切。 |
ATAN2(y, x) | 从直角坐标(x,y)转换为极坐标*(r,theta)的角度theta。 |
DEGREES(expr) | 将以弧度为单位的角度,转换为以度为单位的近似等效角度 |
RADIANS(expr) | 将以度为单位的角度,转换为以弧度为单位的近似等效角度 |
[3] 字符串函数
字符串函数接受字符串,并返回适合该函数的类型
功能 | 描述 |
---|---|
x || y | Concat字符串x和y。 |
CONCAT(expr, expr...) | 连接一个表达式列表。 |
TEXTCAT(expr, expr) | CONCAT的两个参数版本。 |
STRING_FORMAT(pattern[, args...]) | 返回以Java的String.format格式格式化的字符串。 |
LENGTH(expr) | 以UTF-16代码单位表示的expr长度。 |
CHAR_LENGTH(expr) | 与LENGTH同义。 |
CHARACTER_LENGTH(expr) | 与LENGTH同义。 |
STRLEN(expr) | 与LENGTH同义。 |
LOOKUP(expr, lookupName) | 在已经注册的 查询表中查询 expr 。 |
LOWER(expr) | 以所有小写形式返回expr。 |
PARSE_LONG(string[, radix]) | 将字符串解析为具有给定基数的long(BIGINT),如果没有提供基数,则将其解析为10(十进制)。 |
POSITION(needle IN haystack [FROM fromIndex]) | 返回haystack中needle的索引,索引从1开始。搜索将从fromIndex开始;如果未指定fromIndex,则搜索从1开始。如果找不到index,则返回0。 |
REGEXP_EXTRACT(expr, pattern, [index]) | 应用正则表达式模式,并提取捕获组;如果不匹配,则为null。如果index未指定或为零,则返回与模式匹配的子字符串。 |
REPLACE(expr, pattern, replacement) | 使用正则匹配然后做替换,并返回结果。 |
STRPOS(haystack, needle) | 返回haystack中的索引,索引从1开始。如果找不到该索引,则返回0。 |
SUBSTRING(expr, index, [length]) | 返回以最大长度开始的从index开始的expr的子字符串,均以UTF-16代码为单位。 |
RIGHT(expr, [length]) | 返回expr中最右边的字符。 |
LEFT(expr, [length]) | 返回expr中最左边的字符。 |
SUBSTR(expr, index, [length]) | 与SUBSTRING同义。 |
TRIM([BOTH | LEADING | TRAILING] [ FROM] expr) | 如果expr中的字符位于" chars"中,则返回从expr的开头,结尾或两端删除的字符。如果未提供"字符",则默认为""(空格)。如果未提供方向参数,则默认为" 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。 |
REVERSE(expr) | 反转expr。 |
REPEAT(expr, [N]) | 重复expr N次 |
LPAD(expr, length[, chars]) | 从左侧用"字符"填充的" expr"返回字符串" length"。如果"长度"比" expr"的长度短,则结果为" expr",该值被截短为" length"。如果" expr"或" chars"为空,则结果为空。 |
RPAD(expr, length[, chars]) | 从右边用"字符"填充的" expr"返回"长度"的字符串。如果"长度"比" expr"的长度短,则结果为" expr",该值被截短为" length"。如果" expr"或" chars"为空,则结果为空。 |
[4] 时间函数
时间函数可以与Druid的__time列一起使用,任何列都可以通过使用该MILLIS_TO_TIMESTAMP函数来存储毫秒时间戳,或者任何列都可以通过使用该TIME_PARSE 函数来存储字符串时间戳。默认情况下,时间操作使用UTC时区。您可以通过将连接上下文参数" sqlTimeZone"设置为另一个时区的名称(例如" America / Los_Angeles")或偏移量(例如" -08:00")来更改时区。如果您需要在同一查询中混合使用多个时区,或者需要使用连接时区以外的其他时区,则某些函数还接受时区作为参数。这些参数始终优先于连接时区。
可以使用TIMESTAMP '2000-01-01 00:00:00'语法编写连接时区中的文字时间戳记。在其他时区写文字时间戳的最简单方法是使用TIME_PARSE,例如 TIME_PARSE('2000-02-01 00:00:00', NULL, 'America/Los_Angeles')。
功能 | 描述 |
---|---|
CURRENT_TIMESTAMP | 连接时区中的当前时间戳。 |
CURRENT_DATE | 连接时区中的当前日期。 |
DATE_TRUNC(<unit>, <timestamp_expr>) | 四舍五入一个时间戳,并将其作为新时间戳返回。单位可以是"毫秒","秒","分钟","小时","天","周","月","季度","年","十年","世纪"或"千年" '。 |
TIME_CEIL(<timestamp_expr>, <period>, [<origin>, [<timezone>]]) | 汇总时间戳,并将其作为新时间戳返回。期限可以是任何ISO8601期限,例如P3M(季度)或PT12H(半天)。时区(如果提供)应为时区名称(例如" America / Los_Angeles")或偏移量(例如" -08:00")。此功能类似于CEIL但更灵活。 |
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)或YEAR。时区(如果提供)应为时区名称(例如" 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,MICROSECOND,MILLISECOND,SECOND,MINUTE,HOUR,DAY(星期几),DOW(星期几),ISODOW(ISO星期几),DOY(星期几),WEEK(星期几) ,月,季度,年,同年,十年,世纪或千年。单位必须不加报价,例如EXTRACT(HOUR FROM __time)。 |
FLOOR(timestamp_expr TO <unit>) | 四舍五入一个时间戳,并将其作为新时间戳返回。单位可以是秒,分钟,小时,天,周,月,季度或年。 |
CEIL(timestamp_expr TO <unit>) | 汇总时间戳,并将其作为新时间戳返回。单位可以是秒,分钟,小时,天,周,月,季度或年。 |
TIMESTAMPADD(<unit>, <count>, <timestamp>) | 等同于timestamp + count * INTERVAL '1' UNIT。 |
TIMESTAMPDIFF(<unit>, <timestamp1>, <timestamp2>) | 返回unit介于timestamp1和之间的(有符号)数字timestamp2。单位可以是秒,分钟,小时,天,周,月,季度或年。 |
timestamp_expr { + | - } <interval_expr> | 从时间戳中增加或减少时间量。interval_expr可以包含间隔文字,例如INTERVAL '2' HOUR,也可以包含间隔算术。该操作员将日期统一视为86400秒长,并且未考虑夏令时。要考虑夏令时,请改用TIME_SHIFT。 |
[5] IP地址函数
对于IPv4地址功能,自address变量可以是IPv4点分十进制字符串(例如'192.168.0.1'),也可以是表示为整数的IP地址(例如3232235521)。该subnet 参数应该是格式化为CIDR标记的IPv4地址子网中的字符串(如"192.168.0.0/16")。
功能 | 描述 |
---|---|
IPV4_MATCH(address, subnet) | 如果address属于subnet文字,则返回true ,否则返回false。如果address不是有效的IPv4地址,则返回false。如果address是整数而不是字符串,则此函数效率更高。 |
IPV4_PARSE(address) | 解析address为以整数形式存储的IPv4地址。如果address是一个有效的IPv4地址的整数,则将其传递。如果address不能表示为IPv4地址,则返回null 。 |
IPV4_STRINGIFY(address) | 转换address为IPv4地址的点分十进制字符串。如果address是有效的IPv4地址的字符串,则将其传递。如果address不能表示为IPv4地址,则返回null 。 |
[6] 比较运算符
功能 | 描述 |
---|---|
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也不是空字符串,则为true。 |
x IS TRUE | 如果x为true,则为true。 |
x IS NOT TRUE | 如果x不为真,则为真。 |
x IS FALSE | 如果x为假,则为true。 |
x IS NOT FALSE | 如果x不为假,则为真。 |
x IN (values) | 如果x是列出的值之一,则为True。 |
x NOT IN (values) | 如果x不是列出的值之一,则为true。 |
x IN (subquery) | 如果子查询返回x,则为true。 |
x NOT IN (subquery) | 如果子查询未返回x,则为true。 |
x AND y | 布尔AND。 |
x OR y | 布尔值OR。 |
NOT x | 布尔值NOT。 |
[7] 多值的字符串函数
多值字符串函数文档中的所有"数组"引用都可以引用多值字符串列或 ARRAY文字
功能 | 描述 |
---|---|
ARRAY(expr1,expr ...) | 使用第一个参数的类型作为输出数组类型,从表达式参数构造一个SQL ARRAY文字 |
MV_LENGTH(arr) | 返回数组表达式的长度 |
MV_OFFSET(arr,long) | 在提供的基于0的索引处返回数组元素,对于超出范围的索引返回null |
MV_ORDINAL(arr,long) | 在提供的基于1的索引处返回数组元素,对于超出范围的索引返回null |
MV_CONTAINS(arr,expr) | 如果数组包含expr指定的元素,则返回1;如果expr是数组,则包含expr指定的所有元素;否则返回0 |
MV_OVERLAP(arr1,arr2) | 如果arr1和arr2有任何共同的元素,则返回1,否则返回0 |
MV_OFFSET_OF(arr,expr) | 返回expr的第一次出现的0的索引阵列中,或-1或者null如果Druid.generic.useDefaultValueForNull=false如果阵列中不存在匹配的元素。 |
MV_ORDINAL_OF(arr,expr) | 返回数组中第一次出现的expr的基于1的索引,-1或者null如果数组中Druid.generic.useDefaultValueForNull=false不存在匹配的元素,则返回。 |
MV_PREPEND(expr,arr) | 在开头添加expr到arr,结果数组类型由数组类型决定 |
MV_APPEND(arr1,expr) | 将expr附加到arr,结果数组类型由第一个数组的类型确定 |
MV_CONCAT(arr1,arr2) | 连接两个数组,结果数组类型由第一个数组的类型确定 |
MV_SLICE(arr,start,end) | 从从0开始的索引start(包含)到end(不包含)返回arr的子数组,或者null如果start小于0,则大于arr的长度,或者小于end,返回arr的子数组 |
MV_TO_STRING(arr,str) | 通过str指定的分隔符连接arr的所有元素 |
STRING_TO_MV(str1,str2) | 将str1拆分为str2指定的定界符上的数组 |
[8] HLL草图运算符
需要添加DataSketches扩展才能使用
功能 | 描述 |
---|---|
HLL_SKETCH_ESTIMATE(expr, [round]) | 从HLL草图返回不重复计数估计。expr必须返回HLL草图。round如果设置为true,可选的boolean参数将对估算值进行四舍五入,默认值为false。 |
HLL_SKETCH_ESTIMATE_WITH_ERROR_BOUNDS(expr, [numStdDev]) | 从HLL草图返回不重复的计数估计和误差范围。expr必须返回HLL草图。numStdDev可以提供一个可选参数。 |
HLL_SKETCH_UNION([lgK, tgtHllType], expr0, expr1, ...) | 返回HLL草图的并集,其中每个输入表达式必须返回HLL草图。的lgK和tgtHllType可任选地指定为第一参数; 如果提供,则必须指定两个可选参数。 |
HLL_SKETCH_TO_STRING(expr) | 返回以人类可读字符串形式进行调试。expr必须返回HLL草图。 |
[9] Theta草图运算符
需要添加DataSketches扩展才能使用
功能 | 描述 |
---|---|
THETA_SKETCH_ESTIMATE(expr) | 返回theta草图的不重复计数估计。expr必须返回theta草图。 |
THETA_SKETCH_ESTIMATE_WITH_ERROR_BOUNDS(expr, errorBoundsStdDev) | 返回theta草图的不重复计数估计和误差范围。expr必须返回theta草图。 |
THETA_SKETCH_UNION([size], expr0, expr1, ...) | 返回theta草图的并集,其中每个输入表达式必须返回theta草图。在size可任选地指定为第一个参数。 |
THETA_SKETCH_INTERSECT([size], expr0, expr1, ...) | 返回theta草图的交集,其中每个输入表达式必须返回theta草图。在size可任选地指定为第一个参数。 |
THETA_SKETCH_NOT([size], expr0, expr1, ...) | 返回一组Theta草图,其中每个输入表达式必须返回一个Theta草图。在size可任选地指定为第一个参数。 |
[10] 分位数草图运算符
需要添加DataSketches扩展才能使用
功能 | 描述 |
---|---|
DS_GET_QUANTILE(expr, fraction) | 返回与分fraction位数草图对应的分位数估计。expr必须返回分位数草图。 |
DS_GET_QUANTILES(expr, fraction0, fraction1, ...) | 返回一个字符串,该字符串表示与分位数草图中的分数列表相对应的分位数估计值的数组。expr必须返回分位数草图。 |
DS_HISTOGRAM(expr, splitPoint0, splitPoint1, ...) | 在给定分割点列表的情况下,返回一个表示直方图近似值的字符串,该分割点定义了分位数草图中的直方图容器。expr必须返回分位数草图。 |
DS_CDF(expr, splitPoint0, splitPoint1, ...) | 返回一个字符串,该字符串表示给定累积点分布函数的近似值,其中给出了一个拆分点列表,这些拆分点定义了分位数草绘中垃圾箱的边缘。expr必须返回分位数草图。 |
DS_RANK(expr, value) | 返回给定值的秩的近似值,该值是分布的分数小于分位数草图中该值的分数。expr必须返回分位数草图。 |
DS_QUANTILE_SUMMARY(expr) | 返回分位数草图的字符串摘要,可用于调试。expr必须返回分位数草图。 |
[11] 其他功能
功能 | 描述 |
---|---|
CAST(value AS TYPE) | 将值强制转换为另一种类型。 |
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也不是空字符串的值。 |
NVL(expr,expr-for-null) | 如果'expr'为null(或字符串类型为空字符串),则返回'expr-for-null'。 |
BLOOM_FILTER_TEST(<expr>, <serialized-filter>) | 如果该值包含在base64序列化的Bloom筛选器中,则返回true。 |
[12] 不支持的功能
- OVER条款,和分析功能,如LAG和LEAD。
- JOIN子句,除了如上所述的半联接。
- OFFSET子句。
- DDL和DML。
- 多值维度。
- 在DataSketches聚合器上设置操作。
- 空间过滤器。
- 查询取消。
四、 查询的执行(Query execution)
[1] 没有聚合的查询将使用Druid的Scan本机查询类型。
聚合查询(使用GROUP BY,DISTINCT或任何聚合函数)将使用Druid的三种本机聚合查询类型之一。两种(时间序列和TopN)专用于特定类型的聚合,而另一种(GroupBy)则是通用的
-
时间序列
用于查询GROUP BY FLOOR(__time TO <unit>)或TIME_FLOOR(__time, period),没有其他分组表达式,没有HAVING或LIMIT子句,没有嵌套,也没有ORDER BY或按与GROUP BY中相同的表达式排序的ORDER BY的查询。它还将"时间序列"用于具有聚合功能但没有GROUP BY的"总计"查询。这种查询类型利用了Druid段按时间排序的事实
-
TopN
TopN用于由单个表达式分组,具有ORDER BY和LIMIT子句,不具有HAVING子句且未嵌套的查询。但是,在某些情况下,TopN查询类型将提供近似的排名和结果。如果要避免这种情况,请将" use近似TopN"设置为" false"。TopN结果始终在内存中计算。
-
GroupBy
GroupBy用于所有其他聚合,包括任何嵌套的聚合查询。Druid的GroupBy是传统的聚合引擎:它提供准确的结果和排名,并支持多种功能。GroupBy可以在内存中进行聚合,但是如果没有足够的内存来完成查询,则GroupBy可能会溢出到磁盘中。如果您在GROUP BY子句中使用相同的表达式进行ORDER BY,或者根本没有ORDER BY,结果将通过Broker从数据过程中流回。如果查询的ORDER BY引用表达式未出现在GROUP BY子句中(例如聚合函数),则Broker将在内存中具体化结果列表,最多为LIMIT(如果有)。
如果查询执行嵌套聚合(FROM子句中的聚合子查询),则Druid将其作为嵌套GroupBy执行 。在嵌套的GroupBy中,最内部的聚合是分布式的,但是除此以外的所有外部聚合都在查询代理上本地进行。
包含WHERE子句之类的半联接查询col IN (SELECT expr FROM ...)通过特殊过程执行。代理将首先将子查询转换为GroupBy,以查找的不同值expr。然后,代理会将子查询重写为文字过滤器,例如col IN (val1, val2, ...)运行外部查询。配置参数Druid.sql.planner.maxSemiJoinRowsInMemory控制将为此类计划实现的最大值数。
对于所有本机查询类型,该__time列上的过滤器将尽可能转换为顶级查询"间隔",这使Druid可以使用其全局时间索引来快速修剪必须扫描的数据集。此外,Druid将使用每个数据过程本地的索引来进一步加快WHERE评估。通常,对于涉及单个列的引用和函数的布尔组合的过滤器(例如WHERE col1 = 'a' AND col2 = 'b',但不),可以完成此操作 WHERE col1 = col2。
[2] 近似算法
在某些情况下,Druid SQL将使用近似算法:
COUNT(DISTINCT col)默认情况下,聚合函数使用HyperLogLog的变体, HyperLogLog是一种快速的近似非重复计数算法。如果通过查询上下文或通过Broker配置将" useroximateCountDistinct"设置为" false",则Druid SQL将切换到完全不同的计数。
可以使用TopN引擎(使用近似算法)对使用ORDER BY和LIMIT的单列进行GROUP BY查询。如果您通过查询上下文或通过Broker配置将" use近似TopN"设置为" false",则Druid SQL将切换到精确的分组算法。
无论配置如何,APPROX_COUNT_DISTINCT和APPROX_QUANTILE聚合函数始终使用近似算法。
五、客户端API(Client APIs)
[1] 通过Http发送json
可以通过发送json文件的形式进行Druid SQL查询/Druid/v2/sql/。该请求应该是带有“query”字段的JSON对象
-
可以使用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}]
-
可以通过在查询文件中设置context映射进行查询
{ "query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'", "context" : { "sqlTimeZone" : "America/Los_Angeles" } }
-
结果集
{ "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 array JSON数组。每个内部数组都具有按顺序匹配SQL查询返回的列的元素。 应用程序/ json objectLines 类似于“对象”,但是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 }
返回的第一个结果将是标题。对于csv,array和arrayLines格式,标题将是列名的列表。对于object和objectLines格式,标头将是一个对象,其中键是列名,值是null
发送响应正文之前发生的错误将以JSON格式(带有HTTP 500状态代码)报告,格式与本机Druid查询错误相同。如果在发送响应正文时发生错误,则此时更改HTTP状态代码或报告JSON错误就已经晚了,因此响应只会在中途结束,而Druid将记录一个错误,处理您的请求。
作为请求者,正确的处理响应很重要,对于“对象”和“数组”格式,这很容易,因为响应将是无效的JSON。对于面向行的格式,应该检查它们都包含的空白行:在结果集的末尾有一个空白行。如果通过JSON解析错误或缺少的尾随换行符检测到截断的响应,则应假定由于错误而未完正确响应。
[2] JDBC
可以使用Avatica JDBC驱动程序进行Druid SQL查询。下载Avatica客户端jar后,将其添加到类路径并使用connect string 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
}
}
}
元数据可通过JDBC使用connection.getMetaData()或通过查询 “ INFORMATION_SCHEMA”表获得。参数化查询(使用?或其他占位符)无法正常工作,因此请避免使用这些查询。
Druid的JDBC服务器在Broker之间不共享连接状态。这意味着,如果您使用的是JDBC并且有多个Druid Broker,则应该连接到特定的Broker,或者使用启用了共享会话的负载平衡器。Druid Router进程在平衡JDBC请求时提供连接共享性
Druid SQL支持在客户端上设置连接参数。下表中的参数影响SQL规划。您提供的所有其他上下文参数将附加到Druid查询中,并可能影响它们的运行方式。
要为SQL查询指定唯一标识符,请使用sqlQueryId代替queryId。设置queryIdSQL请求无效,所有基于SQL的本机查询都将使用自动生成的queryId
参数 | 描述 | 默认值 |
---|---|---|
sqlQueryId | SQL查询的唯一标识符。对于HTTP客户端,它将在X-Druid-SQL-Query-Id标头中返回。 | 自动产生 |
sqlTimeZone | 此连接的时区,这将影响时间功能和时间戳文字的行为。应为时区名称(例如“ America / Los_Angeles”)或偏移量(例如“ -08:00”)。 | Broker上的Druid.sql.planner.sqlTimeZone(默认值:UTC) |
useApproximateCountDistinct | 是否对s使用近似基数算法COUNT(DISTINCT foo)。 | Broker上的Druid.sql.planner.useroximatedCountDistinct(默认值:true) |
useApproximateTopN | 当查询类似于TopN查询时是否使用近似TopN查询。如果为false,则将使用精确的GroupBy查询。 | Broker上的Druid.sql.planner.use近似TopN(默认值:true) |
六、元数据表(Metadata tables)
Druid Brokers从集群中加载的段中推断出每个数据源的表和列元数据,并以此计划SQL查询。该元数据在Broker启动时被缓存,并通过SegmentMetadata查询在后台定期更新 。后台元数据刷新由进入和退出集群的段触发,也可以通过配置来限制。
Druid通过特殊的系统表公开系统信息。有两种可用的模式:信息模式和系统模式。信息模式提供有关表和列类型的详细信息。系统模式提供有关Druid内部的信息,例如段/任务/服务器。
[1] 信息模式
您可以使用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 没用过 -
Tables表
列 备注 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 DATA_TYPE 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的类型代码(Druid扩展)
[2] 系统模式
系统模式提供了对Druid 的segments, servers and tasks可见性
-
segments表
列 类型 备注 segment_id STRING ID datasource STRING 数据源名称 start STRING 间隔开始时间 end STRING 间隔结束时间 size LONG 段的大小 version STRING 版本 partition_num LONG 分区号 num_replicas LONG 副本数 num_rows LONG 当前段中的行数 is_published LONG 是否已经发布存储到元数据中 is_available LONG 是否可用找到能提供服务的 is_realtime LONG 是否是实时任务提供服务 is_overshadowed LONG 是否此段已发布且被其他已发布段完全覆盖 payload STRING 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
一个段可以由多个流摄取任务或历史进程提供服务,在这种情况下,该段将具有多个副本。这些副本在由多个提取任务提供服务时,彼此之间几乎没有一致性,直到某个段最终由历史记录提供服务为止,此时该段是不可变的。查询节点更喜欢从历史任务中查询一个分段,而不是流摄取任务。但是,如果一个段具有多个实时副本,例如。Kafka索引任务,并且一个任务比其他任务慢,则sys.segments查询结果在任务持续时间内可能会有所不同,因为Broker仅查询一个摄取任务,并且不能保证选择同一任务每次。的num_rows在此期间,细分表的“列”值可能会不一致。
-
Servers表
列 类型 备注 server STRING 服务名称 host STRING 服务的主机名 plaintext_port LONG 服务的不安全端口;如果禁用了纯文本流量,则为-1 tls_port LONG 服务的TLS端口,如果禁用了TLS,则为-1 server_type STRING 服务类型,取值为:COORDINATOR,OVERLORD,BROKER,ROUTER,HISTORICAL,MIDDLE_MANAGER或PEON tier STRING 分发层,仅对HISTORICAL类型有效,对于其他类型则为null current_size LONG 当前服务器上段的当前大小 max_size LONG 当前服务器建议配置的段的最大的设置 要检索有关所有服务器的信息,请使用查询
SELECT * FROM sys.servers;
-
Server_segments表
列 类型 备注 server STRING 服务名称 segment_id STRING 段标识符(段表的主键) “服务器”和“段”之间的JOIN可用于查询特定数据源的段数(按服务器分组)
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;
-
Task表
任务表提供有关活动的和最近完成的索引编制任务的信息
列 类型 备注 task_id STRING ID group_id STRING 任务组ID type STRING 任务类型 datasource STRING 数据源名称 created_time STRING 创建时间 queue_insertion_time STRING 进入Overlord队列的时间 status STRING 任务运行状态 RUNNING, FAILED, SUCCESS runner_status STRING 当前运行的状态,已完成的则为无 正在运行的则为 正在运行 正在等待 duration LONG 任务运行的时间 location STRING 运行所在的机器 主机:端口 host STRING 主机名称 plaintext_port 服务器的不安全端口;如果禁用了纯文本流量,则为-1 tls_port LONG 服务器的TLS端口,如果禁用了TLS,则为-1 error_msg STRING 失败任务时的详细错误消息 要检索按状态过滤的任务信息,请使用查询
SELECT * FROM sys.tasks WHERE status='FAILED';
-
Supervisor表
列 类型 备注 supervisor_id STRING ID state STRING 状态: UNHEALTHY_SUPERVISOR, UNHEALTHY_TASKS, PENDING, RUNNING, SUSPENDED, STOPPING detailed_state STRING 特定状态 healthy LONG 是否是正常的状态 type STRING 类型 source STRING 数据来源 suspended LONG 暂停状态 spec STRING JSON序列化的主管规范 要检索按运行状况过滤的主管任务信息,请使用查询
SELECT * FROM sys.supervisors WHERE healthy=0;
sys表不支持所有Druid SQL函数
七、服务器配置(erver configuration)
Druid的SQL服务的配置是通过查询节点Broker配置的
属性 | 描述 | 默认 |
---|---|---|
Druid.sql.enable | 是否完全启用SQL,包括后台元数据获取。如果为false,它将覆盖所有其他与SQL有关的属性,并完全禁用SQL元数据,服务和计划。 | true |
Druid.sql.avatica.enable | 是否在启用JDBC查询/Druid/v2/sql/avatica/。 | true |
Druid.sql.avatica.maxConnections | Avatica服务器的最大打开连接数。这些不是HTTP连接,而是可能跨越多个HTTP连接的逻辑客户端连接。 | 25 |
Druid.sql.avatica.maxRowsPerFrame | 在单个JDBC框架中返回的最大行数。将此属性设置为-1表示不应用行限制。客户可以选择在请求中指定行数限制;如果客户指定行限制,则将使用客户提供的限制中的较小值maxRowsPerFrame。 | 5,000 |
Druid.sql.avatica.maxStatementsPerConnection | 每个Avatica客户端连接的最大同时打开语句数。 | 4 |
Druid.sql.avatica.connectionIdleTimeout | Avatica客户端连接空闲超时。 | PT5M |
Druid.sql.http.enable | 是否在启用基于HTTP的JSON查询/Druid/v2/sql/。 | true |
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.maxTopNLimit | TopN查询的最大阈值。较高的限制将被计划为GroupBy查询。 | 100000 |
Druid.sql.planner.metadataRefreshPeriod | 节流刷新元数据。 | PT1M |
Druid.sql.planner.useApproximateCountDistinct | 是否对s使用近似基数算法COUNT(DISTINCT foo)。 | true |
Druid.sql.planner.useApproximateTopN | 当可以这样表示SQL查询时是否使用近似TopN查询。如果为false,则将使用精确的GroupBy查询。 | true |
Druid.sql.planner.requireTimeCondition | 是否要求SQL在__time列上具有过滤条件,以便所有生成的本机查询将具有用户指定的间隔。如果为true,则所有在__time列上没有过滤条件的查询都将失败 | false |
Druid.sql.planner.sqlTimeZone | 设置服务器的默认时区,这将影响时间功能和时间戳文字的行为。应为时区名称(例如" America / Los_Angeles")或偏移量(例如" -08:00")。 | 世界标准时间 |
Druid.sql.planner.metadataSegmentCacheEnable | 是否在代理中保留已发布细分的缓存。如果为true,则代理将在后台轮询协调器以从元数据存储中获取分段,并维护本地缓存。如果为false,则当代理需要发布的细分信息时,将调用协调器的REST API。 | false |
Druid.sql.planner.metadataSegmentPollPeriod | 如果Druid.sql.planner.metadataSegmentCacheEnable设置为true,则多久轮询一次协调器以查看已发布的细分列表。轮询周期以毫秒为单位。 | 60000 |
八、SQL指标(SQL Metrics)
Broker将针对SQL发出以下指标
度量 | 描述 | 取值 | 正常值 |
---|---|---|---|
sqlQuery/time | 完成SQL所花费的毫秒数。 | id,nativeQueryIds,dataSource,remoteAddress,成功。 | <1秒 |
sqlQuery/bytes | SQL响应中返回的字节数。 | id,nativeQueryIds,dataSource,remoteAddress,成功。 |