跳转到内容
搜索文档

故障排除指南

最后更新 查看 MarkdownAgent 设置

本指南涵盖了您在使用 R2 SQL 时可能会遇到的潜在错误和限制。R2 SQL 处于公测阶段,支持的功能会随着时间的推移而发展和变化。

查询结构错误

缺少必需的子句

错误: expected exactly 1 table in FROM clause

问题:R2 SQL 要求查询中包含 FROM 子句。

-- 无效 - 缺少 FROM 子句
SELECT user_id WHERE status = 200;

-- 有效
SELECT user_id
FROM my_namespace.http_requests
WHERE status = 200 AND timestamp BETWEEN '2025-09-24T01:00:00Z' AND '2025-09-25T01:00:00Z';

解决方案:始终包含带有完全限定表名的 FROM (namespace_name.table_name)。


FROM 子句问题

JOIN 性能问题

症状:查询返回 502 Bad Gateway 或超时。

问题:大型表之间的多向连接(Multi-way joins)可能会超出资源限制,尤其是在使用 COUNT(DISTINCT) 或其他内存密集型聚合时。

-- 可能超时:交叉连接两个大型事实表
SELECT COUNT(DISTINCT h.ray_id), COUNT(DISTINCT f.event_id)
FROM my_namespace.http_requests h
INNER JOIN my_namespace.firewall_events f ON h.zone_id = f.zone_id

解决方案

  • 添加 WHERE 过滤器以减少中间结果的大小。
  • 通过维度表进行连接,而不是直接连接事实表。
  • 使用 approx_distinct() 代替 COUNT(DISTINCT) 以获得近似计数。
  • 使用 CTE 或顺序查询将复杂的多向连接分解为较小的查询。
-- 更好:过滤双方并使用 approx_distinct
SELECT z.plan,
       approx_distinct(h.ray_id) AS unique_requests
FROM my_namespace.zones z
INNER JOIN my_namespace.http_requests h ON z.zone_id = h.zone_id
WHERE z.plan = 'enterprise'
  AND h.status_code >= 400
GROUP BY z.plan

在可为空(nullable)列上的 NOT IN

症状NOT IN 子查询返回意外结果或错误。

问题:当子查询列可以包含 NULL 值时,不支持 NOT IN 子查询。

-- 失败:nullable_col 可能包含 NULLs
SELECT zone_id
FROM my_namespace.http_requests
WHERE zone_id NOT IN (
    SELECT nullable_col FROM my_namespace.other_table
)
LIMIT 20

解决方案:改用带有相关子查询的 NOT EXISTS

-- 有效:NOT EXISTS 正确处理 NULLs
SELECT h.zone_id
FROM my_namespace.http_requests h
WHERE NOT EXISTS (
    SELECT 1 FROM my_namespace.other_table o
    WHERE o.nullable_col = h.zone_id
)
LIMIT 20

相关子查询(Correlated subquery)性能

症状EXISTSNOT EXISTS 子查询运行缓慢。

问题:具有复杂条件的相关子查询可能会很慢,因为外部查询的每一行都会计算内部查询。

-- 较慢:相关子查询中有多个过滤条件
SELECT z.domain
FROM my_namespace.zones z
WHERE EXISTS (
    SELECT 1 FROM my_namespace.firewall_events f
    WHERE f.zone_id = z.zone_id
      AND f.risk_score > 0.9
      AND f.colo = 'SJC'
)
LIMIT 20

解决方案

  • 尽可能简化相关条件。
  • 考虑使用带有 GROUP BYJOIN 而不是 EXISTS 重写。
  • 使用带有预先聚合结果的 IN 子查询而不是 EXISTS

WHERE 子句问题

JSON 对象过滤

错误: unsupported binary operatorError during planning: could not parse compound

问题:尚未实现 JSON 函数。您无法使用 JSON 路径运算符过滤 JSON 对象内的字段。

-- 无效 - 不支持 JSON 路径运算符
SELECT * FROM my_namespace.requests WHERE json_data->>'level' = 'error'

-- 有效 - 对整个 JSON 列进行过滤
SELECT * FROM my_namespace.logs WHERE json_data IS NOT NULL LIMIT 100

解决方案

  • 将频繁查询的 JSON 字段去规范化(Denormalize)为单独的列。
  • 对整个 JSON 字段进行过滤,并在您的应用程序中处理解析。

LIMIT 子句问题

无效的 limit 值

错误: maximum LIMIT is 10000

问题:LIMIT 值必须介于 1 和 10,000 之间。

-- 无效 - 超出范围
SELECT * FROM my_namespace.events LIMIT 50000

-- 有效
SELECT * FROM my_namespace.events LIMIT 10000

解决方案:使用 1 到 10,000 之间的 LIMIT 值。

分页尝试

错误: unsupported feature: OFFSET clause is not supported

问题:不支持 OFFSET。

-- 无效 - 不支持分页
SELECT * FROM my_namespace.events LIMIT 100 OFFSET 200

-- 有效 - 使用带 ORDER BY 和 WHERE 的基于游标的分页
-- 第 1 页
SELECT * FROM my_namespace.events
WHERE timestamp >= '2024-01-01'
ORDER BY timestamp
LIMIT 100

-- 第 2 页 - 使用上一页的最后一个时间戳
SELECT * FROM my_namespace.events
WHERE timestamp > '2024-01-01T10:30:00Z'
ORDER BY timestamp
LIMIT 100

解决方案:使用 ORDER BYWHERE 条件实现基于游标的分页。


模式 (Schema) 问题

DDL 和 DML 操作

错误: only read-only queries are allowed

问题:R2 SQL 是一种只读查询引擎。不支持 DDL 和 DML 语句。

-- 无效 - 不支持模式更改
ALTER TABLE my_namespace.events ADD COLUMN new_field STRING
UPDATE my_namespace.events SET status = 200 WHERE user_id = '123'
CREATE TABLE my_namespace.test (id INT)
DROP TABLE my_namespace.events

解决方案:通过您的数据提取管道和 R2 Data Catalog 管理您的模式。


性能优化

查询性能问题

如果您的查询运行缓慢:

  1. 始终包含分区(时间戳)过滤器:这是最重要的优化。

    -- 良好 - 将数据扫描范围缩小到一天
    SELECT * FROM my_namespace.events
    WHERE timestamp BETWEEN '2024-01-01' AND '2024-01-02'
    LIMIT 100
  2. 使用选择性过滤:包含特定条件以减少结果集。

    -- 良好 - 多个过滤器减少扫描数据
    SELECT * FROM my_namespace.events
    WHERE status = 200 AND region = 'US' AND timestamp > '2024-01-01'
    LIMIT 100
  3. 选择特定的列:当您只需要几个字段时,请避免使用 SELECT *

    -- 良好 - 仅读取您需要的列
    SELECT user_id, status, timestamp
    FROM my_namespace.events
    WHERE timestamp > '2024-01-01'
    LIMIT 100
  4. 使用 EXPLAIN 检查执行计划:验证谓词下推(predicate pushdown)和文件修剪(file pruning)是否有效。

    EXPLAIN SELECT user_id, status
    FROM my_namespace.events
    WHERE timestamp > '2024-01-01' AND status = 200
  5. 启用压缩(compaction):在 R2 Data Catalog 中启用压缩以减少每个查询扫描的小文件数量。

这篇文档对您有帮助吗?