4. SQL 查询语法基础:SELECT、FROM、WHERE、LIMIT

S3 Select 使用标准 SQL 的子集对 CSV、JSON 或 Parquet 文件进行服务端过滤。掌握 SELECT、FROM、WHERE、LIMIT 四个核心子句,是编写高效查询的起点。本章逐一拆解每个子句的语法规则、执行顺序与性能影响。

4.1 查询语句的完整骨架

一条完整的 S3 Select SQL 查询遵循以下结构。方括号表示可选子句,执行顺序与书写顺序不同:

SELECT [投影表达式]
FROM    s3object
[WHERE  行过滤条件]
[LIMIT  最大返回行数]
执行顺序:FROM → WHERE → SELECT → LIMIT。S3 Select 先确定数据源(FROM),再逐行过滤(WHERE),然后投影列(SELECT),最后截断行数(LIMIT)。理解此顺序有助于预判查询的 I/O 与计算开销。
S3 Select 子句执行顺序与数据流 FROM s3object WHERE 过滤 SELECT 投影 LIMIT 截断 关键原则 WHERE 在 SELECT 之前执行,因此无法在 WHERE 中引用 SELECT 定义的列别名

4.2 SELECT 子句:投影与表达式

SELECT 决定返回哪些列或计算结果。S3 Select 支持以下投影形式:

投影形式示例说明
单列SELECT name直接引用列名
多列SELECT name, age, city逗号分隔多个列
所有列SELECT *返回所有列;注意会增加网络传输量
列别名SELECT name AS user_name使用 AS 重命名输出列
标量函数SELECT CAST(price AS FLOAT)支持 CAST、SUBSTRING、TRIM 等
条件表达式SELECT CASE WHEN age > 18 THEN 'adult' ELSE 'minor' END支持简单 CASE 表达式
性能建议:避免使用 SELECT *,尤其当文件包含大量列或宽字符串列时。显式列出所需列可减少 S3 Select 的序列化开销和网络传输字节数,实测可提升 20%–40% 的查询吞吐。

4.3 FROM 子句:数据源声明

FROM 子句固定使用 s3object 作为表名,代表当前被查询的 S3 对象。S3 Select 不支持多表 JOIN 或子查询,因此 FROM 始终是单表形式:

-- CSV 格式查询
SELECT id, name FROM s3object

-- JSON 格式查询(文档模式)
SELECT id, name FROM s3object

-- JSON 格式查询(行模式)
SELECT id, name FROM s3object[*]

三种数据格式的 FROM 差异:

文件格式FROM 写法行定义
CSVFROM s3object每行一条记录,首行可作列名
JSON(文档模式)FROM s3object整个文件视为单个 JSON 对象,根键映射为列
JSON(行模式)FROM s3object[*]根数组的每个元素作为一行
ParquetFROM s3object列式存储,自动映射列名与类型

4.4 WHERE 子句:行级过滤

WHERE 是性能优化的核心。它决定 S3 Select 在服务端扫描多少行,直接影响扫描字节数和返回行数。支持的过滤操作:

  • 比较运算符:=、<>、<、>、<=、>=
  • 逻辑运算符:AND、OR、NOT
  • 字符串匹配:LIKE(支持 % 和 _ 通配符)
  • 范围判断:BETWEEN ... AND ...
  • 集合判断:IN (...)
  • 空值判断:IS NULL、IS NOT NULL
-- 示例:多条件组合过滤
SELECT order_id, total_amount
FROM s3object
WHERE status = 'shipped'
  AND total_amount BETWEEN 100 AND 500
  AND region IN ('NA', 'EU')
注意:S3 Select 的 WHERE 子句不支持子查询、聚合函数(如 COUNT、SUM)或用户自定义函数。所有过滤逻辑必须基于单行数据内的列值。

4.5 LIMIT 子句:控制输出行数

LIMIT 用于限制最终返回给客户端的行数。它在 WHERE 过滤之后、SELECT 投影之后执行,因此不会减少服务端的扫描行数:

-- 只返回前 10 条满足条件的记录
SELECT id, name, score
FROM s3object
WHERE score > 80
LIMIT 10

LIMIT 的典型使用场景:

  • 数据采样:快速查看文件内容结构,无需全量扫描
  • 分页预览:配合应用层游标实现分批拉取
  • 调试查询:验证 WHERE 条件是否正确,避免返回海量数据
误区澄清:LIMIT 不能降低 S3 Select 的计费扫描量。S3 Select 按“扫描的数据字节数”计费,即使只返回 1 行,如果 WHERE 条件扫描了 1 GB 数据,仍按 1 GB 收费。因此,优化 WHERE 条件才是控制成本的关键。
WHERE 过滤 vs LIMIT 截断:扫描量与返回量 场景 A:无 WHERE + LIMIT 10 扫描 100 万行(全表) 返回 10 行 计费扫描量:100 万行 场景 B:WHERE + LIMIT 10 扫描 100 万行(全表) WHERE 过滤后剩余 200 行 LIMIT 截断后返回 10 行 计费扫描量:100 万行(不变)

4.6 子句组合实战:典型查询模式

将四个子句组合使用,可以覆盖绝大多数 S3 Select 查询场景。以下表格列出常见模式及其适用场景:

模式SQL 示例适用场景
全量预览SELECT * FROM s3object LIMIT 5快速查看文件列名与样本数据
条件过滤SELECT id FROM s3object WHERE status = 'active'提取活跃记录 ID 列表
范围查询SELECT * FROM s3object WHERE ts BETWEEN '2024-01-01' AND '2024-01-31'按时间窗口过滤日志
分页拉取SELECT id, name FROM s3object WHERE id > 1000 LIMIT 500基于游标的分页(避免 OFFSET)
数据采样SELECT city, temp FROM s3object WHERE city = 'Beijing' LIMIT 100特定城市的温度样本
最佳实践:在开发阶段始终带上 LIMIT 10 或 LIMIT 100,避免意外返回 GB 级数据导致客户端 OOM。确认 WHERE 条件正确后,再移除 LIMIT 进行全量查询。

4.7 常见语法错误与排查

S3 Select 的 SQL 解析器对语法敏感,以下是最常见的三类错误:

  • 列名引用错误:CSV 文件使用 _1、_2 作为默认列名(若无表头);JSON 文件区分大小写,SELECT Name 与 SELECT name 不同。
  • 字符串引号错误:S3 Select 要求字符串字面量使用单引号 'value',双引号保留给列名或别名。
  • 不支持的功能:使用 JOIN、GROUP BY、ORDER BY、DISTINCT 等会直接返回语法错误。
-- 错误示例(不支持 ORDER BY)
SELECT name FROM s3object ORDER BY name
-- → S3 Select 返回:SQL 语法错误

-- 正确做法:在客户端排序
SELECT name FROM s3object WHERE name IS NOT NULL

掌握 SELECT、FROM、WHERE、LIMIT 四个子句,你已经可以编写 90% 以上的 S3 Select 查询。下一层优化将围绕 WHERE 条件的谓词下推与数据类型对齐展开,这是提升扫描效率的关键。