# TQL

> 介绍了 `TQL` 关键字及其在 GreptimeDB 中的用法，包括 `EVAL`、`EXPLAIN` 和 `ANALYZE` 的语法和示例。

# TQL

`TQL` 关键字在 SQL 中执行 TQL 语言。TQL 是 Telemetry Query Language 的缩写，是 GreptimeDB 中对 Prometheus 的 [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics/) 的扩展。

## EVAL

### Syntax

```sql
TQL [EVAL | EVALUATE] (start, end, step, [lookback]) expr [AS alias]
```

`start`, `end` 和 `step` 是查询参数，就像 [Prometheus Query API](https://prometheus.io/docs/prometheus/latest/querying/api/) 一样：

- `start`: `<rfc3339 | unix_timestamp | expression >`: 查询的起始时间戳，范围中包含该值。
- `end`: `<rfc3339 | unix_timestamp | expression>`: 查询的截止时间戳，范围中包含该值。
- `step`: `<duration | float>`: 查询分辨率步长，采用 `duration` 格式或浮点秒数。
- `lookback`: `<duration | float>`: 查询评估的最大过去持续时间，默认 5 分钟，可选参数。

`expr` 是 TQL (PromQL) 的查询字符串。

可选的 `AS alias` 子句允许你为结果中的值列指定自定义名称。这对以下场景很有用：
- 为查询结果提供有意义的名称
- 在 SQL 查询中使用 TQL 结果（例如 CTE、JOIN）
- 提高复杂查询的可读性

**注意**：值别名目前仅支持单值列结果。

### 示例

返回过去 5 分钟内 `http_requests_total` 指标的所有时间序列的每秒值：

```sql
TQL EVAL (1677057993, 1677058993, '1m')
  rate(prometheus_http_requests_total{job="prometheus"}[5m]);
```

其查询结果和 SQL 查询结果类似。

使用值别名为结果提供自定义名称：

```sql
TQL EVAL (0, 30, '10s') http_requests_total AS requests;
```

这将返回值列名为 `requests` 而不是默认字段名的结果。

值别名与聚合：

```sql
TQL EVAL (0, 10, '5s') count by (k) (test) AS count_value;
```

此查询按 `k` 分组计数值，并将结果列命名为 `count_value`。

`start` 和 `end` 还可以是可以被求值为常量的时间表达式，例如查询过去 3 个小时：

```sql
TQL EVAL (now() - interval '3' hours, now(), '1m')
  sum by (namespace, pod) (
    increase(kube_pod_container_status_restarts_total[10m:30s])
  );
```

查询过去一天的数据：
```sql
TQL EVAL (
  date_trunc('day', now() - interval '1' day),
  date_trunc('day', now()),
  '1m'
)
  sum by (namespace) (
    rate(http_requests_total[5m:30s])
  );
```

### 在 CTE 中使用 TQL

TQL `EVAL` 可以在公共表表达式（CTE）中使用，以便将 PromQL 风格的查询与 SQL 处理相结合。有关详细示例和使用指南，请参阅[在 CTE 中使用 TQL](/user-guide/query-data/cte.md#在-cte-中使用-tql)。

## EXPLAIN

`EXPLAIN` 展示特定 PromQL 查询的逻辑计划和执行计划，其语法如下：

```
TQL EXPLAIN [VERBOSE] [FORMAT format] [(start, end, step, [lookback])] expr [AS alias];
```

例如，我们可以使用下方示例解释 PromQL `sum by (instance) (rate(node_disk_written_bytes_total[2m])) > 50`：

```
TQL EXPLAIN sum by (instance) (rate(node_disk_written_bytes_total[2m])) > 50;
```

注意该查询实际上没有被执行，所以 `(start, end, step, [lookback])` 不是必需的，但你仍然可以像在 `TQL EVAL` 中一样提供这些参数：

```
TQL EXPLAIN (0, 100, '10s') sum by (instance) (rate(node_disk_written_bytes_total[2m])) > 50;
```

你也可以在 EXPLAIN 中使用值别名：

```
TQL EXPLAIN (0, 10, '5s') test AS series;
```

结果如下：

```txt
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| plan_type     | plan                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| logical_plan  | Sort: node_disk_written_bytes_total.instance ASC NULLS LAST, node_disk_written_bytes_total.ts ASC NULLS LAST
  Filter: SUM(prom_rate(ts_range,field,ts)) > Float64(50)
    Aggregate: groupBy=[[node_disk_written_bytes_total.instance, node_disk_written_bytes_total.ts]], aggr=[[SUM(prom_rate(ts_range,field,ts))]]
      Projection: node_disk_written_bytes_total.ts, prom_rate(ts_range, field, node_disk_written_bytes_total.ts) AS prom_rate(ts_range,field,ts), node_disk_written_bytes_total.instance
        Filter: prom_rate(ts_range, field, node_disk_written_bytes_total.ts) IS NOT NULL
          Projection: node_disk_written_bytes_total.ts, node_disk_written_bytes_total.instance, field, ts_range
            PromRangeManipulate: req range=[0..0], interval=[300000], eval range=[120000], time index=[ts], values=["field"]
              PromSeriesNormalize: offset=[0], time index=[ts], filter NaN: [true]
                PromSeriesDivide: tags=["instance"]
                  Sort: node_disk_written_bytes_total.instance DESC NULLS LAST, node_disk_written_bytes_total.ts DESC NULLS LAST
                    TableScan: node_disk_written_bytes_total projection=[ts, instance, field], partial_filters=[ts >= TimestampMillisecond(-420000, None), ts <= TimestampMillisecond(300000, None)] |
| physical_plan | SortPreservingMergeExec: [instance@0 ASC NULLS LAST,ts@1 ASC NULLS LAST]
  SortExec: expr=[instance@0 ASC NULLS LAST,ts@1 ASC NULLS LAST]
    CoalesceBatchesExec: target_batch_size=8192
      FilterExec: SUM(prom_rate(ts_range,field,ts))@2 > 50
        AggregateExec: mode=FinalPartitioned, gby=[instance@0 as instance, ts@1 as ts], aggr=[SUM(prom_rate(ts_range,field,ts))]
          CoalesceBatchesExec: target_batch_size=8192
            RepartitionExec: partitioning=Hash([Column { name: "instance", index: 0 }, Column { name: "ts", index: 1 }], 32), input_partitions=32
              AggregateExec: mode=Partial, gby=[instance@2 as instance, ts@0 as ts], aggr=[SUM(prom_rate(ts_range,field,ts))]
                ProjectionExec: expr=[ts@0 as ts, prom_rate(ts_range@3, field@2, ts@0) as prom_rate(ts_range,field,ts), instance@1 as instance]
                  CoalesceBatchesExec: target_batch_size=8192
                    FilterExec: prom_rate(ts_range@3, field@2, ts@0) IS NOT NULL
                      ProjectionExec: expr=[ts@0 as ts, instance@1 as instance, field@2 as field, ts_range@3 as ts_range]
                        PromInstantManipulateExec: req range=[0..0], interval=[300000], eval range=[120000], time index=[ts]
                          PromSeriesNormalizeExec: offset=[0], time index=[ts], filter NaN: [true]
                            PromSeriesDivideExec: tags=["instance"]
                              RepartitionExec: partitioning=RoundRobinBatch(32), input_partitions=1
                                ExecutionPlan(PlaceHolder)
 |
+---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
```

## ANALYZE

TQL 同样支持 `ANALYZE` 关键词来分析给定 PromQL 查询的执行，其语法如下：

```
TQL ANALYZE [VERBOSE] [FORMAT format] (start, end, step, [lookback]) expr [AS alias];
```

例如：

```
TQL ANALYZE (0, 10, '5s') test;
```

得到结果：

```
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| plan_type         | plan                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Plan with Metrics | CoalescePartitionsExec, metrics=[output_rows=0, elapsed_compute=14.99µs]
  PromInstantManipulateExec: range=[0..10000], lookback=[300000], interval=[5000], time index=[j], metrics=[output_rows=0, elapsed_compute=1.08µs]
    PromSeriesNormalizeExec: offset=[0], time index=[j], filter NaN: [false], metrics=[output_rows=0, elapsed_compute=1.11µs]
      PromSeriesDivideExec: tags=["k"], metrics=[output_rows=0, elapsed_compute=1.3µs]
        RepartitionExec: partitioning=RoundRobinBatch(32), input_partitions=32, metrics=[send_time=32ns, repart_time=32ns, fetch_time=11.578016ms]
          RepartitionExec: partitioning=RoundRobinBatch(32), input_partitions=1, metrics=[send_time=1ns, repart_time=1ns, fetch_time=21.07µs]
            ExecutionPlan(PlaceHolder), metrics=[]
      |
+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
```

使用 `TQL ANALYZE VERBOSE` 可以拿到查询执行时更详细的信息.

```
TQL ANALYZE VERBOSE (0, 10, '5s') test;
```
