跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

故障排除指南

最后更新 查看 MarkdownAgent 设置

本指南介绍使用 Basin SQL 时可能遇到的错误和限制。

查询结构错误

缺少必需的子句

错误: expected exactly 1 table in FROM clause

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

-- Invalid - Missing FROM clause
SELECT user_id WHERE status = 200;

-- Valid
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) 或其他内存密集型聚合时。

-- May timeout: cross-joining two large fact tables
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 或顺序查询将复杂的多向连接分解为较小的查询。
-- Better: filter both sides and use 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 子查询。

-- Fails: nullable_col may contain 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。

-- Works: NOT EXISTS handles NULLs correctly
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)性能

症状:EXISTS 或 NOT EXISTS 子查询运行缓慢。

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

-- Slower: multiple filter conditions in correlated subquery
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 BY 的 JOIN 而不是 EXISTS 重写。
  • 使用带有预先聚合结果的 IN 子查询而不是 EXISTS。

WHERE 子句问题

JSON 对象过滤

错误: unsupported binary operator 或 Error during planning: could not parse compound

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

-- Invalid - JSON path operators not supported
SELECT * FROM my_namespace.requests WHERE json_data->>'level' = 'error'

-- Valid - Filter on the entire JSON column
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 之间。

-- Invalid - Out of range
SELECT * FROM my_namespace.events LIMIT 50000

-- Valid
SELECT * FROM my_namespace.events LIMIT 10000

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

模式 (Schema) 问题

DDL 和 DML 操作

错误: only read-only queries are allowed

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

-- Invalid - Schema changes not supported
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

解决方法:通过数据摄取 pipeline 和 Basin Catalog 管理架构。


性能优化

查询性能问题

如果您的查询运行缓慢:

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

    -- Good - Narrows data scan to one day
    SELECT * FROM my_namespace.events
    WHERE timestamp BETWEEN '2024-01-01' AND '2024-01-02'
    LIMIT 100
  2. 使用选择性过滤:包含特定条件以减少结果集。

    -- Good - Multiple filters reduce scanned data
    SELECT * FROM my_namespace.events
    WHERE status = 200 AND region = 'US' AND timestamp > '2024-01-01'
    LIMIT 100
  3. 选择特定的列:当您只需要几个字段时,请避免使用 SELECT *。

    -- Good - Only reads the columns you need
    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. 启用压缩合并:在 Basin Catalog 中启用压缩合并,减少每次查询扫描的小文件数量。

这篇文档对您有帮助吗?