SPL语法

更新时间:2026-08-28 16:27:45

SPL (SLS Processing Language) — 日志服务管道式数据处理语言。语句以 | 分割:查询语句 | 分析语句

1. 基础语法

SPL 语句结构

<data-source> | <spl-expr> | <spl-expr> ;
  • * = LogStore 全部数据
  • | = 管道符,前级输出为后级输入
  • ; = 语句结束符(末尾可省略)

语法符号

符号 说明
* LogStore 数据占位符
. SPL 关键字前缀(如 .let
\| 管道符
'...' 字符串常量
"..." 字段名 / 字段名模式
-- / /*...*/ 单行 / 多行注释
$ 命名数据集引用($name

数据类型

类型 说明
VARCHAR 可变字符(除时间字段外,SPL 输入字段初始类型均为 VARCHAR
BOOLEAN / TINYINT / SMALLINT / INTEGER / BIGINT / HUGEINT 整数系列
REAL / DOUBLE 浮点数
TIMESTAMP 纳秒精度 UNIX 时间戳
DATE YYYY-MM-DD
ARRAY 数组,下标从 1 开始,a[1]
MAP 字典,a['foo']
JSON JSON 类型

2. SPL 指令速查

指令表达式语法:cmd -option=<value> -flag <expression> as <output>, ...

2.1 控制指令

.let — 定义命名数据集

.let <name> = <spl-expr>
.let err = * | where status >= 500 | extend msg='ERR';
$err;   -- 输出命名数据集

2.2 字段操作

project — 保留/重命名字段

| project -wildcard <pattern>, <new>=<old>, ...
* | project level, err_msg
* | project log_level=level
* | project -wildcard "__tag__:*"

默认保留 __time____time_ns_part__,不可重命名或覆盖。

project-away — 移除字段

| project-away -wildcard <pattern>, ...
* | project-away -wildcard "__tag__:*"

project-rename — 重命名字段

| project-rename <new>=<old>, ...
* | project-rename log_level=level

2.3 SQL 计算指令

extend — 通过 SQL 表达式产生新字段(重名直接覆盖)

| extend <output>=<sql-expr>, ...
* | extend Duration = EndTime - StartTime
* | extend a = json_extract(content, '$.body.a')
* | extend status = cast(status as BIGINT)
* | extend k1='v1', k2='v2', k3='v3'          -- 合并多个 extend

where — 根据 SQL 表达式过滤数据

| where <sql-expr>
* | where userId = '123'
* | where cast(status as BIGINT) >= 500
* | where regexp_like(server_protocol, '\d+')
* | where a = 'x' and b = 'y'                  -- 合并多个 where

2.4 聚合指令

stats — 聚合统计

stats <alias>=<aggFunc> by <group>, ...
聚合函数
count, count_if, min, max, sum, avg, skewness, kurtosis, approx_percentile, approx_distinct, bool_and, bool_or, every, arbitrary, array_agg
* | stats pv = count(*) by ip
* | stats pv = count(*)                         -- 无分组全局统计
* | extend lat = cast(latencyMs as bigint) | stats minLat=min(lat), maxLat=max(lat) by ip

默认返回前 100 条,配合 limit 获取更多。

sort — 排序

sort <field> [asc|desc], ...
* | sort latencyMs desc

limit — 限制行数

limit (<offset>,) <size>
* | sort latencyMs | limit 1
* | limit 5, 10                                 -- 跳过5条取10条

不配合 sort 时,limit 输出顺序随机。


3. SQL 分析语法

查询语句 | 分析语句
  • 查询语句可单独使用;分析语句必须与查询语句一起使用
  • 分析语句无需 FROM/WHERE(默认分析当前 LogStore),不区分大小写,末尾不加分号
  • 分析语句不支持 offset
* | SELECT status, count(*) AS PV GROUP BY status

4. 查询语句语法

4.1 全文查询

keywords1 [ and | or | not ] keywords2 ...
  • 多个关键词之间默认 and 关系
  • 通配符 *(0+字符)、?(1字符),不能用在词开头
GET
GET or POST
Jo?                    -- Joe, Jon 等
cn*                    -- 以 cn 开头的词

4.2 字段查询

field [ : | > | >= | < | <= | = | in ] value [ and | or | not ... ]

运算符速查

运算符 说明 示例
: Key:Value status:200
and / or / not 逻辑运算 status:200 and method:GET
( ) 优先级 (GET or POST) and status:200
"" 包裹特殊字符/关键词 "file info":apsara, "and"
* / ? 通配符 host:www*com, host:aliyund?c
> >= < <= 比较(long/double) request_time>100
= 等于(long/double) request_time=100
in [a b] / in (a b) 闭区间/开区间 status in [200 299]
__source__ 日志源 __source__:192.0.2.*
__tag__ 元数据 __tag__:__receive_time__:1609...
__topic__ 日志主题 __topic__:nginx_access_log

运算符优先级(高→低)

:, "", (), and/not, or

字段类型与可用运算符

类型 可用运算符
text and, or, not, (), :, "", *, ?
long/double and, or, not, (), >, >=, <, <=, =, in
JSON 按内部字段类型

特殊查询

需求 语句
字段值不为空 not remote_user:""
字段值为空 remote_user:""
字段不存在 not remote_user:*
字段存在 remote_user:*
原始日志全文搜索 * \| where __line__ like '%error%'
字段名含空格 "request method":PUT
保留字当关键词 "and"
短语精确匹配 #"redo_index/1"

5. SQL 子句

子句 说明
SELECT 选择列,支持 AS 别名
FROM log 指定 LogStore(嵌套子查询中必须显式写)
WHERE 过滤条件
GROUP BY 分组聚合,支持 ROLLUP、CUBE、GROUPING SETS
HAVING 过滤分组/聚合结果
ORDER BY 排序,ASC/DESC
LIMIT 限制行数(默认 100)
JOIN 连接多表(跨 Logstore / MySQL / OSS)
UNION 合并多个 SELECT 结果
INTERSECT 返回交集
EXCEPT 返回差集
EXISTS 判断子查询是否有结果
UNNEST 展开数组/map 字段
WITH 子查询保存为临时表
VALUES 构造临时数据
INSERT INTO 写入计算结果到其他 Logstore

6. SQL 保留字段

AND, AS, BETWEEN, BY, CASE, CAST, CROSS, CUBE,
CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP,
DISTINCT, ELSE, END, ESCAPE, EXCEPT, EXISTS,
FROM, GROUP, GROUPING, HAVING, IN, INNER,
INSERT, INTERSECT, INTO, IS, JOIN, LEFT, LIKE,
LIMIT, LOCALTIME, LOCALTIMESTAMP, NATURAL, NOT,
NULL, ON, OR, ORDER, OUTER, RIGHT, ROLLUP,
SELECT, THEN, TRUE, UNION, UNNEST, VALUES,
WHEN, WHERE, WITH

7. 嵌套子查询

子查询用 () 包裹,内部须写 FROM log

-- 基础
* | SELECT key FROM (sub_query)

-- 求最小 PV
* | SELECT min(PV) FROM (
    SELECT count(1) as PV FROM log GROUP BY request_method
)

-- 同比
* | SELECT diff[1] AS today, diff[2] AS yesterday, diff[3] AS ratio
FROM (
    SELECT compare(PV, 86400) AS diff FROM (
        SELECT count(*) AS PV FROM log
    )
)

-- 占比(窗口函数)
* | SELECT uri, c, round(c * 100.0 / sum(c) over(), 2) AS "占比%"
FROM (SELECT request_uri AS uri, count(*) AS c FROM log GROUP BY uri)

8. 函数分类速查

分类 常用函数
聚合 count, count_if, min, max, sum, avg, array_agg
字符串 concat, length, position, replace, split, split_part, chr
日期时间 current_date, date_parse, date_format, date_trunc, date_add, to_unixtime, day
JSON json_extract, json_extract_scalar, json_array_get, json_array_length, json_parse
正则 regexp_extract, regexp_extract_all, regexp_like, regexp_replace, regexp_split
类型转换 cast, try_cast, typeof
条件表达式 CASE WHEN ... THEN ... ELSE ... END, IF, COALESCE, NULLIF, TRY
数组 array_distinct, array_join, reverse, filter, reduce, transform, []
Map cardinality, element_at, histogram, map
数学 abs, ceil, round, log, mod, random
统计 corr, covar_pop, regr_intercept, beta_cdf
窗口 dense_rank, lag + 聚合函数
同比环比 compare, ts_compare
预测 ts_predicate_simple
比较 >, >=, <, <=, =, !=, BETWEEN, IS NULL, IS NOT NULL, LIKE, IN, ALL, ANY
逻辑 AND, OR, NOT
IP ip_to_province, ip_to_city, ip_prefix, ipv6_to_city
URL url_encode, url_decode, url_extract_path, url_extract_query
估算 approx_distinct, approx_percentile, numeric_histogram
二进制 from_base64, from_hex, to_hex, sha256
位运算 bitwise_and, bitwise_or, bitwise_not, bit_count
地理 geohash, ST_AsText, ST_Contains, ST_Buffer
HyperLogLog approx_set, cardinality, merge
窗口漏斗 window_funnel
单位换算 convert_data_size, format_duration

9. 常用场景速查

9.1 SPL vs SQL

场景 SQL SPL
过滤 WHERE Type='write' \| where Type='write'
选字段+重命名 SELECT a AS x, b \| project x=a, b
排除字段 \| project-away -wildcard "tag:*"
计算新字段 SELECT cast(s AS BIGINT) \| extend s = cast(s as BIGINT)
聚合 SELECT count(*) PV GROUP BY ip \| stats pv=count(*) by ip

9.2 关键注意事项

  • 类型转换:除时间字段外,SPL 输入字段初始均为 VARCHAR,比较前需 cast
    * | where cast(status as BIGINT) >= 500
    
  • extend 后类型保持:转换后后续管道沿用新类型
  • 合并管道:多个 where/extend 应合并为一个以减少管道数
  • 时间字段__time____time_ns_part__ 默认保留,只能通过 extend 修改
  • NULL:字段不存在或计算异常时值为 null,用 COALESCE 兜底
  • 大小写:查询场景字段名大小写不敏感,其他场景敏感
  • 字符转义:字符串内单引号用 '' 转义;\ 不作为转义符;特殊字符用 chr() 拼接
本篇文档内容对您是否有帮助?
有帮助
我要反馈
提交成功!非常感谢您的反馈,我们会继续努力做到更好!