-- +goose Up
-- Каталог разрезов отвечает по учётным колонкам объекта, а не по его
-- содержимому. Без индекса это невозможно: `bucket` объявлена `WITHOUT ROWID`,
-- то есть строка целиком, вместе со сжатым `payload`, живёт в дереве первичного
-- ключа. Агрегат по всем строкам тащил бы за собой страницы содержимого — при
-- 260 тысячах объектов за год это сотни мегабайт чтения на каждый запрос
-- каталога, притом что сам ответ несёт три десятка строк.
--
-- Индекс ПОКРЫВАЮЩИЙ: в нём есть всё, что спрашивает каталог, поэтому обращения
-- к самой таблице не будет вовсе. Порядок колонок задан двумя запросами:
--
--   1. разрезы метрики  — GROUP BY metric, layer (+ units, чтобы расхождение
--      единиц было видно строкой, а не выбиралось молча);
--   2. общие часы двух слоёв — обход hour_utc по убыванию внутри (metric,
--      layer), поэтому hour_utc стоит третьим и до колонок значений.
--
-- Первичный ключ (metric, layer, hour_utc) в индекс дописывается самим SQLite:
-- у таблицы `WITHOUT ROWID` строка адресуется им.
--
-- Цена — около 60 байт на объект (≈16 МБ за год) и одна вставка в дерево на
-- запись объекта. Платит её только настоящее изменение: широкий проход, у
-- которого сошёлся хеш содержимого, объект не переписывает вовсе.
CREATE INDEX bucket_catalog ON bucket (metric, layer, hour_utc, first_ts, last_ts, points, units);

-- +goose Down
DROP INDEX bucket_catalog;
