Transcript
00:00:00Хотя я безумно люблю Postgres, он идеален далеко не во всём. Существует другой тип
00:00:04баз данных — колоночные базы данных, которые могут выполнять определённые запросы до 40 раз быстрее. Эти
00:00:10базы данных работают, сохраняя столбцы вместе, а не строки, что дает огромные преимущества
00:00:15для определённых сценариев использования, таких как аналитические платформы. Конечно, за всё приходится платить,
00:00:20но сегодня мы подробно рассмотрим, что такое колоночные базы данных, и сравним несколько запросов
00:00:25с Postgres, чтобы увидеть плюсы и минусы. Мы сравним Postgres с ClickHouse и DuckDB,
00:00:31так что оставайтесь с нами, и к концу вы получите четкое представление о колоночных базах данных
00:00:36и о том, когда какую технологию использовать.
00:00:43Итак, в начале я сказал, что некоторые запросы можно выполнять в 40 раз быстрее, и это правда. Если взять
00:00:49таблицу базы данных — здесь я загрузил сто миллионов строк — и запустить запрос с группировкой в
00:00:55Postgres, то на его выполнение уходит примерно 9,7 секунды, потому что мы агрегируем выручку из каждой
00:01:00каждая строка, если мы выполним тот же запрос по тому же набору данных с использованием столбцовой базы данных, и это
00:01:06используя буквально тот же самый SQL (и ClickHouse, и DuckDB имеют синтаксис SQL, похожий на Postgres, так что вам
00:01:13всё будет знакомо) — ClickHouse справляется за 0,28 секунды, а DuckDB за 0,24 секунды. Это более чем в 40 раз быстрее!
00:01:22Как это возможно? Кажется невероятным, верно? Те же 100 миллионов строк обрабатываются всего за 0,24 секунды.
00:01:30Просто колоночные базы данных выполняют на порядки меньше работы для получения тех же результатов.
00:01:36Давайте посмотрим на другой запрос в действии. И небольшая ремарка, ребята: мы постоянно выпускаем контент об ИИ и технологиях,
00:01:42так что если вам это нравится, почему бы не подписаться на Better Stack? На этот раз мы подсчитываем количество
00:01:47событий между двумя метками времени, где код страны равен gb. В нашем случае мы смотрим на данные за
00:01:53март. Результаты: Postgres — 5,9 секунды, ClickHouse — 0,06 секунды и DuckDB — 0,03 секунды. Март содержит
00:02:02около 13 процентов всех событий, поэтому Postgres по-прежнему приходится просматривать миллионы строк. Мы могли бы
00:02:09добавить сюда агрессивное индексирование, но это не приблизит нас к ClickHouse и DuckDB. Так почему же
00:02:15колоночные хранилища здесь намного быстрее? Что ж, ClickHouse вообще не индексирует отдельные строки. Когда вы создаете
00:02:20таблицу, вы задаете ей ключ сортировки, и данные сортируются по метке времени, после чего отсортированные данные разбиваются на блоки по
00:02:32и сохраняется только информация о первой метке времени в каждом из них. Для 100 миллионов строк это около 12 000 записей,
00:02:39и это достаточно мало, чтобы поместиться в памяти. Поэтому, когда мы запрашиваем март, система быстро ищет среди этих
00:02:44записей, находит блоки, которые могут содержать март, и считывает только их. В нашем случае это 1633 блока из
00:02:5212 208, а всё остальное на диске пропускается. DuckDB делает нечто похожее, поскольку хранит минимальное
00:03:00и максимальное значения для каждого чанка столбца. Таким образом, мы можем посмотреть на чанк, увидеть, что метки времени идут с января по
00:03:06февраль, и полностью пропустить его, даже не читая. Добавьте к этому трюк из прошлого примера, где открываются
00:03:10только нужные столбцы, и вы получаете 0,03 секунды. Но всё кардинально меняется, когда вам нужно
00:03:17выбрать одну единственную строку по ID. Этот простой запрос многое проясняет: Postgres тратит две миллисекунды, ClickHouse — 168
00:03:26миллисекунд, а DuckDB, что интересно, укладывается всё в те же две миллисекунды. У Postgres есть индекс на основе B-дерева для
00:03:32поля ID, поэтому он спускается по дереву, попадает на ту единственную страницу, где хранится строка, и всё готово всего за
00:03:37две миллисекунды. Но с ClickHouse у нас проблемы: его единственный индекс — это ключ сортировки, а эта таблица
00:03:43отсортирована сначала по метке времени, а во вторую очередь — по ID. Поэтому, когда мы запрашиваем конкретный ID, база понятия не имеет, в каком блоке
00:03:51он находится, и в итоге проверяет каждый из 12 208 блоков. И даже найдя строку, ей всё равно
00:03:57приходится открывать все восемь файлов столбцов и собирать строку заново, что является огромным объемом работы для столь
00:04:03простого запроса. Так как же DuckDB сходит это с рук? Ей просто повезло с нашими данными: ID вставлялись по
00:04:09порядку, поэтому минимум и максимум в каждом чанке аккуратно совпадают с ID, и DuckDB может перейти прямо к нужному
00:04:16чанку. Если бы ID были перемешаны, ей пришлось бы сканировать весь столбец, точно так же как ClickHouse. Давайте теперь посмотрим
00:04:21на обновление строки. У нас есть один запрос для Postgres и DuckDB и немного другая версия для
00:04:26ClickHouse. Postgres справился за 5 миллисекунд, ClickHouse — за 5,8 секунды, а DuckDB — снова всего за десятки
00:04:34миллисекунд. Postgres просто перезаписывает одну строку и обновляет одну запись в индексе. В ClickHouse файлы данных
00:04:40неизменяемы, они никогда не редактируются на месте, поэтому для изменения одного значения выручки приходится перезаписывать
00:04:46весь файл столбца выручки для этого чанка таблицы. ClickHouse даже заставляет писать это как операцию
00:04:51ALTER TABLE, поскольку воспринимает это как мутацию всей таблицы. Существует более легкое обновление в
00:04:56бета-версии, но оно предназначено только для небольшого числа строк — примерно до 10 процентов таблицы максимум. DuckDB занимает промежуточное
00:05:03положение между ними, поскольку её файл может изменяться на месте, поэтому обновление одной строки занимает несколько десятков
00:05:08миллисекунд. И наконец, давайте подсчитаем количество уникальных пользователей в нашей таблице (снова с небольшой
00:05:14модификацией запроса для ClickHouse). Результаты таковы: Postgres — 38,4 секунды, ClickHouse — 0,78 секунды,
00:05:22а DuckDB — меньше секунды. Опять же, Postgres страдает: агрегация по всей столь огромной таблице
00:05:28просто требует колоссального объема работы. Теперь, вы, вероятно, захотите использовать колоночные базы данных для таких задач, как аналитика,
00:05:34где агрегирование данных по различным столбцам является обычной задачей. Здесь мы рассмотрели два варианта: ClickHouse
00:05:41представляет собой хостинговый сервер с открытым исходным кодом, доступный на большинстве основных платформ. Чтобы запустить его локально, вам нужно запустить
00:05:47сервер ClickHouse на своем компьютере, что ближе к тому, как работает Postgres. DuckDB, однако, больше похожа на SQLite:
00:05:54это библиотека, которая работает внутри собственного процесса, а вся база данных живет в одном файле на диске. Из-за этого
00:06:00файл может быть заблокирован во время выполнения обновления, что сводит на нет параллелизм. Обе базы являются колоночными,
00:06:06но используют совершенно разные подходы. Так что выбор базы данных в итоге сводится к гораздо большему,
00:06:12чем я могу предположить здесь. Дело не только в чистой скорости выполнения запросов при тестировании на локальном компьютере,
00:06:17но и в масштабируемости, избыточности и расширяемости. Конечно, у Postgres есть богатая экосистема плагинов для
00:06:24расширения функционала самыми разными способами, о чем вы можете узнать из этого видео.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video