Какой запрос быстрее работает в колоночной базе данных, а какой в строковой
Что проверяют
Понимаете ли вы, как способ хранения на диске определяет, какие запросы дешёвые, а не просто помните пару OLAP и OLTP. Следом часто спрашивают, почему SELECT * в колоночной базе считается плохой практикой или почему там дорог UPDATE одной строки.
Как отвечать
Начните с устройства. Строковая база (PostgreSQL, MySQL) кладёт все поля строки рядом на одной странице. Колоночная (ClickHouse, Vertica, BigQuery, Snowflake, Redshift, DuckDB, а из форматов файлов Parquet и ORC) хранит каждую колонку отдельно.
Быстрые запросы в колоночной базе:
- агрегации по нескольким колонкам на миллионах строк:
SELECT department, avg(salary) FROM employees GROUP BY departmentчитает две колонки из, скажем, пятидесяти; - аналитика по событиям и метрикам: однотипные значения подряд хорошо сжимаются (словарь, RLE, дельта-кодирование), обработка идёт векторно, пачками значений;
- пропуск блоков: по min/max и разреженному индексу база не читает куски, которые не подходят под условие. В ClickHouse одна метка первичного индекса по умолчанию покрывает гранулу в 8192 строки.
Быстрые запросы в строковой базе:
- точечное чтение:
SELECT * FROM employees WHERE id = 123через B-tree за несколько чтений страниц, вся строка лежит в одном месте; - частые
INSERT,UPDATE,DELETEотдельных строк в транзакциях.
В колоночной базе тот же SELECT * по ключу собирает строку из десятков файлов, а изменение одной строки часто означает перезапись целого куска данных.
Где спотыкаются
Называют Cassandra или HBase колоночными базами. Это wide-column хранилища: данные там организованы по ключу строки, и для аналитических сканов по колонкам они не предназначены.
Говорят, что колоночная база просто быстрее на чтение. На точечных запросах с SELECT * она проигрывает обычному PostgreSQL.
Забывают про запись: вставка по одной строке в ClickHouse плодит мелкие куски и нагружает слияния. Данные копят и вставляют пачками или включают асинхронную вставку.