← R2 SQL / r2-sql
Руководство по устранению неполадок
В этом руководстве описаны возможные ошибки и ограничения, с которыми вы можете столкнуться при использовании R2 SQL. R2 SQL находится в открытой бета-версии, и поддерживаемая функциональность будет развиваться и меняться со временем.
Ошибки структуры запроса
Отсутствуют обязательные предложения
Ошибка: expected exactly 1 table in FROM clause
Проблема: Для работы R2 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
Проблемы с производительностью соединений
Симптом: Запрос возвращает 502 Bad Gateway или завершается по тайм-ауту.
Проблема: Многосторонние соединения между большими таблицами могут превышать лимиты ресурсов, особенно с 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.planNOT IN для столбцов, допускающих NULL
Симптом: NOT IN подзапрос возвращает неожиданные результаты или ошибки.
Проблема: NOT IN подзапросы не поддерживаются, если столбец подзапроса может содержать NULL значения.
-- 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Производительность коррелированных подзапросов
Симптом: 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Решение:
- По возможности упрощайте коррелированные условия.
- Попробуйте переписать это как
JOINсGROUP BYвместоEXISTS. - Используйте
INподзапрос с предварительно агрегированными результатами вместоEXISTS.
Проблемы с предложением WHERE
Фильтрация объектов JSON
Ошибка: unsupported binary operator или Error during planning: could not parse compound
Проблема: Функции JSON пока не реализованы. Фильтрация по полям внутри объектов JSON с помощью операторов JSON path не поддерживается.
-- 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 в отдельные столбцы.
- Фильтруйте по всему полю 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Решение: Используйте значения LIMIT от 1 до 10,000.
Попытки пагинации
Ошибка: unsupported feature: OFFSET clause is not supported
Проблема: OFFSET не поддерживается.
-- Invalid - Pagination not supported
SELECT * FROM my_namespace.events LIMIT 100 OFFSET 200
-- Valid - Use cursor-based pagination with ORDER BY and WHERE
-- Page 1
SELECT * FROM my_namespace.events
WHERE timestamp >= '2024-01-01'
ORDER BY timestamp
LIMIT 100
-- Page 2 - Use the last timestamp from the previous page
SELECT * FROM my_namespace.events
WHERE timestamp > '2024-01-01T10:30:00Z'
ORDER BY timestamp
LIMIT 100Решение: Реализуйте курсорную пагинацию с использованием ORDER BY и WHERE условия.
Проблемы со схемой
Операции DDL и DML
only read-only queries are allowedПроблема: R2 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Решение: Управляйте схемой через пайплайн приёма данных и R2 Data Catalog.
Оптимизация производительности
Проблемы с производительностью запросов
Если ваши запросы выполняются медленно:
-
Всегда указывайте фильтры по партиции (timestamp): Это самая важная оптимизация.
-- Good - Narrows data scan to one day SELECT * FROM my_namespace.events WHERE timestamp BETWEEN '2024-01-01' AND '2024-01-02' LIMIT 100 -
Используйте выборочную фильтрацию: Указывайте конкретные условия, чтобы уменьшить объём результирующих наборов.
-- Good - Multiple filters reduce scanned data SELECT * FROM my_namespace.events WHERE status = 200 AND region = 'US' AND timestamp > '2024-01-01' LIMIT 100 -
Выбор определённых столбцов: избегайте
SELECT *если вам нужно всего несколько полей.-- Good - Only reads the columns you need SELECT user_id, status, timestamp FROM my_namespace.events WHERE timestamp > '2024-01-01' LIMIT 100 -
Используйте EXPLAIN, чтобы посмотреть план выполнения: Убедитесь, что проброс предикатов и отсечение файлов работают.
EXPLAIN SELECT user_id, status FROM my_namespace.events WHERE timestamp > '2024-01-01' AND status = 200 -
Включение уплотнения: Включите уплотнение в R2 Data Catalog, чтобы уменьшить количество мелких файлов, сканируемых при каждом запросе.