druid sql part-13
This commit is contained in:
parent
708897f8f8
commit
4fdd5daf92
@ -3,4 +3,5 @@
|
|||||||
### `table`
|
### `table`
|
||||||
### `lookup`
|
### `lookup`
|
||||||
### `union`
|
### `union`
|
||||||
|
### `inline`
|
||||||
### `join`
|
### `join`
|
@ -497,12 +497,144 @@ SQL中的子查询一般被转换为原生的查询数据源。有关如何执
|
|||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> WHERE子句中的子查询,如:`WHERE col1 IN (SELECT foo FROM ...)`,被转化为内连接
|
> WHERE子句中的子查询,如:`WHERE col1 IN (SELECT foo FROM ...)`,被转化为内连接
|
||||||
|
|
||||||
|
|
||||||
#### 近似
|
#### 近似
|
||||||
#### 不支持的特征
|
|
||||||
|
Druid SQL在一些场景中使用近似算法:
|
||||||
|
|
||||||
|
* 默认情况下,`COUNT(DISTINCT col)` 聚合函数使用 [HyperLogLog](http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf) 的变体,HyperLogLog是一种快速近似的DISTINCT计数算法。如果通过查询上下文或通过Broker配置将"useApproximateCountDistinct"设置为"false",Druid SQL将切换到精确计数
|
||||||
|
* 对于具有ORDER BY和LIMIT的单列GROUP BY查询,可以采用使用了近似算法的TopN引擎执行查询。如果通过查询上下文或通过Broker配置将"useApproximateTopN"设置为"false",Druid SQL将切换到精确的分组算法
|
||||||
|
* 标记为使用草图或近似(例如近似计数不同)的聚合函数不管配置如何,始终是近似的
|
||||||
|
|
||||||
|
#### 不支持的特性
|
||||||
|
|
||||||
|
Druid SQL并非支持所有的SQL特性。 以下特性不支持:
|
||||||
|
* 原生数据源(table, lookup, subquery)与系统表的JOIN操作
|
||||||
|
* 左侧和右侧的表达式之间不相等的JOIN条件
|
||||||
|
* OVER子句,`LAG` 和 `LEAD` 等分析型函数
|
||||||
|
* OFFSET子句
|
||||||
|
* DDL和DML
|
||||||
|
* 在 [元数据表](#元数据表) 上使用Druid特性的函数,比如 `TIME_PARSE` 和 `APPROX_QUANTILE_DS`
|
||||||
|
|
||||||
|
另外,一些Druid原生查询中的特性目前还不被SQL支持。 不支持的特性如下:
|
||||||
|
* [UNION数据源](datasource.md#union)
|
||||||
|
* [INLINE数据源](datasource.md#inline)
|
||||||
|
* [空间过滤器](spatialfilter.md)
|
||||||
|
* [查询取消](makeNativeQueries.md#查询取消)
|
||||||
|
|
||||||
### 客户端API
|
### 客户端API
|
||||||
#### HTTP
|
#### HTTP POST
|
||||||
|
|
||||||
|
在Druid SQL查询中,可以通过HTTP方式发送POST请求到 `/druid/v2/sql` 来执行SQL查询。该请求应该是一个带有 "query" 字段的JSON对象,例如: `{"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar'"}`
|
||||||
|
|
||||||
|
**Request**
|
||||||
|
|
||||||
|
| 属性 | 描述 | 默认值 |
|
||||||
|
|-|-|-|
|
||||||
|
| `query` | SQL | 必填,无 |
|
||||||
|
| `resultFormat` | 查询结果的格式,详情查看下边的response部分 | object |
|
||||||
|
| `header` | 是否包含一个请求头,详情查看下边的response部分 | false |
|
||||||
|
| `context` | 包括 [连接上下文](#连接上下文) 参数JSON对象 | {}(空) |
|
||||||
|
| `parameters` | 参数化查询的查询参数列表。列表中的每个参数都应该是一个JSON对象,比如 `{"type":"VARCHAR","value":"foo"}` 。`type` 应为SQL类型;有关支持的SQL类型的列表,请参见 [数据类型](#数据类型) | [](空) |
|
||||||
|
|
||||||
|
可以在命令行中使用 *curl* 来发送SQL查询:
|
||||||
|
|
||||||
|
```json
|
||||||
|
$ 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"的参数来添加 [连接上下文](#连接上下文) 变量,例如:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
|
||||||
|
"context" : {
|
||||||
|
"sqlTimeZone" : "America/Los_Angeles"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
参数化SQL查询也是支持的:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = ? AND __time > ?",
|
||||||
|
"parameters": [
|
||||||
|
{ "type": "VARCHAR", "value": "bar"},
|
||||||
|
{ "type": "TIMESTAMP", "value": "2000-01-01 00:00:00" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
通过对 [元数据表](#元数据表) 进行HTTP POST请求可以获得元数据
|
||||||
|
|
||||||
|
**Responses**
|
||||||
|
|
||||||
|
Druid SQL的HTTP POST API支持一个可变的结果格式,可以通过"resultFormat"参数来指定,例如:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
|
||||||
|
"resultFormat" : "object"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
支持的结果格式为:
|
||||||
|
|
||||||
|
| 格式 | 描述 | Content-Type |
|
||||||
|
|-|-|-|
|
||||||
|
| `object` | 默认值,JSON对象的JSON数组。每个对象的字段名都与SQL查询返回的列匹配,并且按与SQL查询相同的顺序提供。| application/json |
|
||||||
|
| `array` | JSON数组的JSON数组。每个内部数组按顺序都有与SQL查询返回的列匹配的元素。 | application/json |
|
||||||
|
| `objectLines` | 与"object"类似,但是JSON对象由换行符分隔,而不是包装在JSON数组中。如果您没有流式JSON解析器的现成访问权限,这可以使将整个响应集解析为流更加容易。为了能够检测到被截断的响应,此格式包含一个空行的尾部。 | text/plain |
|
||||||
|
| `arrayLines` | 与"array"类似,但是JSON数组由换行符分隔,而不是包装在JSON数组中。如果您没有流式JSON解析器的现成访问权限,这可以使将整个响应集解析为流更加容易。为了能够检测到被截断的响应,此格式包含一个空行的尾部。 | text/plain |
|
||||||
|
| `csv` | 逗号分隔的值,每行一行。单个字段值可以用双引号括起来进行转义。如果双引号出现在字段值中,则通过将它们替换为双引号(如`""this""`)来对其进行转义。为了能够检测到被截断的响应,此格式包含一个空行的尾部。 | text/csv |
|
||||||
|
|
||||||
|
您还可以通过在请求中将"header"设置为true来请求头,例如:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
|
||||||
|
"resultFormat" : "arrayLines",
|
||||||
|
"header" : true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在这种情况下,返回的第一个结果将是头。对于 `csv`、`array` 和 `arrayline` 格式,标题将是列名列表。对于 `object` 和 `objectLines` 格式,头将是一个对象,其中键是列名,值为空。
|
||||||
|
|
||||||
|
在发送响应体之前发生的错误将以JSON格式报告,状态代码为HTTP 500,格式与 [原生Druid查询错误](makeNativeQueries.md#查询错误) 相同。如果在发送响应体时发生错误,此时更改HTTP状态代码或报告JSON错误已经太迟,因此响应将简单地结束流,并且处理您的请求的Druid服务器将记录一个错误。
|
||||||
|
|
||||||
|
作为调用者,正确处理响应截断非常重要。这对于"object"和"array"格式很容易,因为的截断响应将是无效的JSON。对于面向行的格式,您应该检查它们都包含的尾部:结果集末尾的一个空行。如果通过JSON解析错误或缺少尾随的换行符检测到截断的响应,则应假定响应由于错误而未完全传递。
|
||||||
|
|
||||||
#### JDBC
|
#### JDBC
|
||||||
|
|
||||||
|
您可以使用 [Avatica JDBC Driver](https://calcite.apache.org/avatica/downloads/) 来进行Druid SQL查询。 下载Avatica客户端jar包后加到类路径下,使用如下连接串: `jdbc:avatica:remote:url=http://BROKER:8082/druid/v2/sql/avatica/`
|
||||||
|
|
||||||
|
示例代码为:
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 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()` 或者查询 [信息Schema](#信息Schema)
|
||||||
|
|
||||||
|
**连接粘性**
|
||||||
|
|
||||||
|
Druid的JDBC服务不在Broker之间共享连接状态。这意味着,如果您使用JDBC并且有多个Druid Broker,您应该连接到一个特定的Broker,或者使用启用了粘性会话的负载平衡器。Druid Router进程在平衡JDBC请求时提供连接粘性,即使使用普通的非粘性负载平衡器,也可以用来实现必要的粘性。请参阅 [Router文档](../Design/Router.md) 以了解更多详细信息
|
||||||
|
|
||||||
#### 动态参数
|
#### 动态参数
|
||||||
#### 连接上下文
|
#### 连接上下文
|
||||||
### 元数据表
|
### 元数据表
|
||||||
|
@ -1 +1,4 @@
|
|||||||
<!-- toc -->
|
<!-- toc -->
|
||||||
|
## 原生查询
|
||||||
|
### 查询取消
|
||||||
|
### 查询错误
|
Loading…
x
Reference in New Issue
Block a user