Счётчик архива: платишь за прочитанные байты
Чему научишься
- считать стоимость запроса до его запуска: модель «платишь за прочитанные байты»
- объяснять, почему
SELECT *— деньги на ветер, аLIMITсчёт не уменьшает - пользоваться dry-run и кэшем результатов
- понимать, когда компании выгодны слоты вместо оплаты за байты
Утренний счёт
Утро начинается с вызова: комендант станции переслал тебе ведомость. За вчерашние запросы к Дальнему архиву счётчик списал заметный кусок энергии станции-донора — и рядом с каждым запросом стоит цифра.
Ты просматриваешь список и замечаешь странное: самый «дорогой» запрос вернул пять строк. Самый дешёвый — пятьдесят. Цена явно не про количество строк в ответе.
КВЕРИ: Я разобрал прейскурант архива, пока ты спал. Плохая новость: платят тут не за ответ, а за чтение. Хорошая: значит, ценой можно управлять.

Модель on-demand: байты, а не строки
BigQuery в базовом режиме (on-demand) берёт деньги за одно: сколько байтов таблиц запрос прочитал. В земных деньгах — около 6,25 $ за прочитанный ТиБ (первый ТиБ в месяц бесплатный). ТиБ — тебибайт, двоичный терабайт: 1024 ГиБ ≈ 1,1 «обычного» ТБ. Прайс Google считает именно в них, поэтому и курс тоже. Счётчик станции устроен так же, просто валюта другая.
Вспомни прошлый урок: данные лежат колонками. Поэтому объём чтения считается просто:
скан = сумма размеров прочитанных колонок целиком
SELECT name FROM fa_users— прочитана одна колонкаname, по всем строкам таблицы;SELECT * FROM fa_users— прочитаны ВСЕ колонки;- количество строк в ответе на счёт не влияет вообще.
В Postgres ты о «стоимости» SELECT не думал: сервер твой, диск твой, разница между быстрым и медленным запросом — минуты ожидания. В BigQuery у каждого запроса есть цена в деньгах — и она известна ДО запуска.
Почему LIMIT не экономит
Привычка из строчного мира: «поставлю LIMIT 10 — базе меньше работы». В строчной базе это похоже на правду: прочитал десять строк с начала — остановился.
Колоночный движок работает иначе: чтобы отдать тебе хоть одну строку, он уже прочитал нужные колонки целиком — распределённо, большими блоками. LIMIT применяется в самом конце, к готовому результату. Счёт к этому моменту уже выставлен.
То же с WHERE (пока таблица не партиционирована — об этом глава «Деньги и масштаб»): фильтр уменьшает число строк в ответе, но колонки из WHERE и SELECT всё равно прочитаны по всей таблице.
Прикинем. Представь, что журнал событий колонии дорос до продовых размеров: десять колонок примерно одного веса, всего 5 ТиБ — по ~500 ГиБ на колонку. Тогда:
-- прочитает ~1 ТиБ (две колонки целиком): ~6,25 $
SELECT user_id, event_name FROM journal;
-- прочитает РОВНО столько же: ~6,25 $
SELECT user_id, event_name FROM journal LIMIT 100;
-- прочитает все 5 ТиБ: ~31 $
SELECT * FROM journal LIMIT 100;
Один SELECT * «на посмотреть» — как оставить кран открытым: вода уже утекла, сколько бы стаканов ты ни налил.
Dry-run: цена до запуска. Кэш: повтор бесплатно
Главный инструмент выживания — dry-run: прогон запроса без исполнения. BigQuery разбирает запрос, смотрит таблиц и возвращает точный объём будущего скана — бесплатно и мгновенно. В консоли BigQuery оценка видна прямо при наборе («This query will process 1.2 TB when run»), в CLI — bq query --dry_run, в API — флаг dryRun.
Привычка EXPLAIN из Postgres здесь превращается в привычку dry-run: там ты смотрел план, чтобы сберечь минуты, — здесь смотришь байты, чтобы сберечь деньги.
Второй друг — кэш результатов. Повторяешь в точности тот же запрос, а данные не менялись — BigQuery отдаёт сохранённый результат бесплатно (кэш живёт примерно сутки). Поэтому «запустить ещё раз посмотреть» не страшно; страшно «чуть поменять и прогнать по всей таблице заново». Что именно ломает кэш (например, недетерминированные функции вроде CURRENT_TIMESTAMP()) — разберём в главе «Деньги и масштаб».
Слоты: когда байты считать надоело
У модели «за байты» есть потолок: когда запросов становится очень много, компания переходит на capacity-модель — покупает слоты, единицы вычислительной мощности, и платит за них фиксированно, сколько бы байтов ни читали запросы. На неё переходят, когда нагрузка стала постоянной или когда компании важнее заранее знать потолок расходов, чем считать цену каждого запроса. Это выбор администратора, а не аналитика: тарификация меняется, синтаксис — нет.
Для тебя правило простое: пока счёт идёт за байты — каждая лишняя колонка стоит денег; если в компании слоты — неэкономный запрос всё равно отнимает общую мощность у коллег. Дешёвые привычки окупаются в обеих моделях.
Песочница курса бесплатна — и потому честное предупреждение: эмулятор не считает байты и не умеет dry-run. Числа в этом уроке — арифметика по прейскуранту реального BigQuery. В заведи рефлекс: сначала dry-run, потом запуск.
SELECT user_id, event_name FROM journal LIMIT 100 и каков счёт при тарифе 6,25 $/ТиБ?Главное из урока
- on-demand: платишь за прочитанные байты колонок, ~6,25 $ за ТиБ; строки в ответе ни при чём
LIMITиWHERE(без партиций) счёт не уменьшают: колонки читаются целиком до них- dry-run показывает точную цену до запуска; точный повтор запроса отдаётся из кэша бесплатно
- слоты — capacity-модель для больших команд; дешёвые привычки нужны в обеих
Привычка Postgres → идиома BigQuery (часть 1):
| Привычка из Postgres | Как в BigQuery |
|---|---|
SELECT * «глянуть данные» | список колонок или SELECT * EXCEPT(...) |
LIMIT 10 «чтобы дёшево» | LIMIT только про размер вывода; цену не меняет |
EXPLAIN перед тяжёлым запросом | dry-run: точные байты до запуска |
CREATE INDEX | нет: партиции и кластеризация (глава 5) |
| «база сама закэширует» | кэш результатов: точный повтор — бесплатно |
Документация: тарифы BigQuery, лучшие практики стоимости.
Счётчик понят. Но архив хранит данные, записанные в спешке умирающими колониями, — в них мусор, а запросу нельзя умирать. Следующий урок — SAFE-режим.