Pull to refresh
181
35.1
Боровиков Кирилл @Kilor

Архитектура ИС: PostgreSQL, Node.js и highload

Send message

Курс «PostgreSQL для начинающих»: #4 — Анализ запросов (ч.1 — как и зачем читать планы)

Level of difficultyMedium
Reading time16 min
Views17K

Продолжаю публикацию расширенных транскриптов лекционного курса "PostgreSQL для начинающих", подготовленного мной в рамках "Школы backend-разработчика" в "Тензоре".

В этой лекции мы узнаем, что такое план выполнения запроса, как и зачем его читать (и почему это совсем непросто), и о каких проблемах с производительностью базы он может сигнализировать. Разберем, что такое Seq Scan, Bitmap Heap Scan, Index Scan и почему Index Only Scan бывает нехорош, чем отличается Materialize от Memoize, а Gather Merge от "просто" Gather.

Как обычно, для предпочитающих смотреть и слушать, а не читать - доступна видеозапись (часть 1, часть 2).

Читать далее
Total votes 33: ↑32.5 and ↓0.5+32
Comments4

SQL HowTo: один индекс на два диапазона

Level of difficultyMedium
Reading time3 min
Views3.7K

В прошлой статье я показал, как условие с парой однотипных неравенств, плохо поддающееся индексации с помощью btree, можно переделать на эффективно gist-индексируемое в PostgreSQL условие относительно диапазонных типов, а наш сервис анализа планов запросов explain.tensor.ru подскажет, как именно это сделать.

Но что делать, если неравенств у нас не два, а целых четыре, да еще и с разными типами участвующих полей? Например, для целей бизнеса это может быть задачей вроде "найди мне все продажи за декабрь на сумму 10-20K", что на SQL будет выглядеть примерно так:

dt >= '2023-12-01'::date AND dt <= '2023-12-31'::date AND

sum >= 10000::numeric AND sum <= 20000::numeric

Читать далее
Total votes 21: ↑21 and ↓0+21
Comments7

Бьемся с индексацией парных неравенств в PostgreSQL

Level of difficultyMedium
Reading time6 min
Views4K

Я уже не раз писал, что условия с несколькими неравенствами (<, <=, >=, >) обычно плохо подходят для индексирования "классическим" btree, вызывают "тормоза", и необходимо придумывать различные нетривиальные подходы в PostgreSQL, чтобы добиться хорошей производительности подобного запроса.

В этой статье мы не только рассмотрим способы решения подобных задач "в общем виде", но и покажем, как нам удалось автоматизировать их решение в рамках функционала рекомендаций индексов нашего сервиса анализа планов explain.tensor.ru и его новых возможностях.

Читать далее
Total votes 18: ↑18 and ↓0+18
Comments2

Курс «PostgreSQL для начинающих»: #3 — Сложные SELECT

Level of difficultyMedium
Reading time12 min
Views26K

Продолжаю публикацию расширенных транскриптов лекционного курса "PostgreSQL для начинающих", подготовленного мной в рамках "Школы backend-разработчика" в "Тензоре".

В этой лекции углубимся в расширенные возможности команды SELECT : как можно "сложить" и "вычесть" выборки (UNION/INTERSECT/EXCEPT), или запомнить и использовать в рекурсивных запросах (CTE), что дают оконные функции (WINDOW) и соединения (JOIN).

Как обычно, для предпочитающих смотреть и слушать, а не читать - доступна видеозапись.

Читать далее
Total votes 36: ↑35 and ↓1+34
Comments7

PostgreSQL в «Тензоре» — публикации за год (#4)

Level of difficultyEasy
Reading time2 min
Views2.8K

Под занавес уходящего года предлагаю традиционно вспомнить, про какие интересные возможности и особенности работы с PostgreSQL мы рассказали в нашем блоге.

Если не видели дайджест за прошлый год — время наверстать упущенное!

Читать далее
Total votes 5: ↑5 and ↓0+5
Comments0

SQL HowTo: итоги по строкам и столбцам «в одно действие»

Level of difficultyMedium
Reading time4 min
Views14K

Немного отвлечемся от простых SELECT и посмотрим на реальной бизнес-задаче построения различных "тепловых карт" и "шахматок", как знание возможностей SQL может облегчить жизнь и разработчику, и его базе.

Читать далее
Total votes 27: ↑27 and ↓0+27
Comments14

Курс «PostgreSQL для начинающих»: #2 — Простые SELECT

Level of difficultyEasy
Reading time14 min
Views17K

Продолжаю публикацию расширенных транскриптов лекционного курса "PostgreSQL для начинающих", подготовленного мной в рамках "Школы backend-разработчика" в "Тензоре".

Сегодня поговорим о самых простых, но важных, возможностях команды SELECT, наиболее часто используемой при работе с базами данных - формировании выборок (VALUES), их ограничении (LIMIT/OFFSET/FETCH), фильтрации (WHERE/HAVING), сортировке (ORDER BY), уникализации (DISTINCT) и группировке (GROUP BY).

Как обычно, для предпочитающих смотреть и слушать, а не читать - доступна видеозапись.

Читать далее
Total votes 13: ↑13 and ↓0+13
Comments6

Курс «PostgreSQL для начинающих»: #1 — Основы SQL

Level of difficultyEasy
Reading time13 min
Views43K

Этим постом я запускаю публикацию расширенных транскриптов лекционного курса "PostgreSQL для начинающих", подготовленного мной в рамках "Школы backend-разработчика" в "Тензоре".

В программе: рассказ об основах SQL, возможностях простых и сложных SELECT, анализ производительности запросов, разбор [не]эффективного применения индексов и особенностей работы транзакций и блокировок в этой СУБД.

Курс не претендует на лавры "войти в айти", поэтому подразумевает наличие у слушателя опыта программирования или работы с другими СУБД, и, главное, желания самостоятельно изучать тему работы с PostgreSQL глубже.

Для тех, кому комфортнее смотреть и слушать, а не читать - доступна видеозапись.

Читать далее
Total votes 35: ↑34 and ↓1+33
Comments30

SQL HowTo: TOP-N на субинтервалах

Level of difficultyEasy
Reading time3 min
Views4.4K

Периодически сталкиваюсь с однотипными задачами вида "показать TOP-N позиций на каждом из вложенных интервалов некоторого периода".

Это может быть "5 лучших по успеваемости студентов в каждом семестре за последний учебный год", или "помесячная динамика позиции 10 наиболее продающихся товаров", или, как у нас в сервисе визуализации PostgreSQL-планов explain.tensor.ru, "3 наиболее активных страны за каждый день":

Читать далее
Total votes 11: ↑11 and ↓0+11
Comments14

PostgreSQL Antipatterns: ходим по JSON-граблям

Level of difficultyEasy
Reading time3 min
Views14K

Недавно попался на глаза примерно такой кусок запроса, и тут прекрасно примерно все:

множество чтений из CTE (хоть и единственной записи, но все же);

извлечение по каждому ключу текста с раскастовкой в jsonb;

извлечение каждого отдельного json-ключа в каждое отдельное одноименное поле;

"ручное" преобразование текстового представления массива в json в текстовое представление PostgreSQL.

А как - правильно?

Читать далее
Total votes 26: ↑26 and ↓0+26
Comments13

SQL HowTo: ближайший общий предок в дереве (LCA)

Level of difficultyMedium
Reading time5 min
Views4.1K

В иерархических структурах регулярно возникает потребность определить ближайшего общего предка в дереве, он же наименьший общий предок (Lowest (Least) Common Ancestor).

Правда, "классические" алгоритмы для решения этой задачи работают лишь с парой узлов (раз, два, три, четыре), а мы, используя всю мощь PostgreSQL, будем решать задачу сразу для нескольких узлов.

Читать далее
Total votes 13: ↑13 and ↓0+13
Comments4

Всегда ли хорош Index Only Scan?

Level of difficultyMedium
Reading time5 min
Views9.1K

Среди применяемых в PostgreSQL методов доступа к данным Index Only Scan стоит особняком, считаясь у многих разработчиков "волшебной пилюлей" для ускорения работы запроса - мол, "Index Scan - плохо, Index Only Scan - хорошо, как только получим его в плане - все станет замечательно".

Как минимум, это утверждение неверно. Как максимум, при определенных условиях может вызвать проблемы чуть ли не на ровном месте.

Читать далее
Total votes 27: ↑26 and ↓1+25
Comments3

Кэш в JavaScript: не все Map'ы одинаково полезны

Level of difficultyEasy
Reading time2 min
Views5.9K

При разработке приложений регулярно возникает задача кэширования каких-то данных, которые из хранилища должны читаться много чаще, чем писаться. Давайте рассмотрим на примере простого теста, когда и на каком механизме эффективнее организовать его для JavaScript-приложения - на Map или на Object.

Читать далее
Total votes 14: ↑14 and ↓0+14
Comments15

SQL HowTo: замена в строке по набору

Level of difficultyEasy
Reading time2 min
Views4.2K

Решим сегодня простую, казалось бы, задачу: как на PostgreSQL можно в строке провести замены по набору пар строк. То есть в исходной строке 'abcdaaabbbcccdcba' заменить, например, 'а' -> 'x', 'bb' -> 'y', 'ccc' -> 'z' и получить 'xbcdxxxybzdcbx'.

Фактически, мы попробуем создать аналог str_replace или strtr.

Читать далее
Total votes 9: ↑9 and ↓0+9
Comments4

SQL HowTo: крупицы золота в реестре

Level of difficultyHard
Reading time7 min
Views8.7K

В большинстве учетных систем, типа нашего СБИС, рано или поздно возникает проблема быстрого отображения реестра, в который по просьбам бизнес‑пользователей накручено несколько комбинируемых фильтров с очень редкой выборкой, ну никак не ложащихся в вашу красивую структуру базы данных и индексов базовой таблицы реестра — что‑нибудь типа "список продаж покупателям, чей день рождения выпадает на 29 февраля".

Универсального способа сделать «хорошо» тут нет, но я расскажу про модель запроса, которая позволит вам дать пользователю быстрый отклик, но при этом весьма эффективно с точки зрения PostgreSQL.

Читать далее
Total votes 18: ↑18 and ↓0+18
Comments9

Node.js: Клонирование ключей. Is eval() evil?

Reading time5 min
Views3K

На примере простой задачи клонирования ключей объекта посмотрим, есть ли реальные альтернативы по производительности столь презираемой JavaScript-разработчиками функции eval().

Подобная задача возникает, если оригинальное значение ключа надо оставить у объекта, а как-то обработанное - положить рядом в новый соответствующий ключ. То есть, для начала, из {"a" : 1, "b" : 2} надо получить {"a" : 1, "a-copy" : 1, "b" : 2, "b-copy" : 2}.

Пару лет назад я уже рассказывал, почему максимальная производительность подобных операций на JavaScript важна для нашего сервиса потокового анализа логов PostgreSQL, как можно поускорять парсинг с помощью WebAssembly, и вот сегодня - продолжение.

Читать далее
Total votes 12: ↑12 and ↓0+12
Comments12

PostgreSQL Antipatterns: Индиана Джонс и максимальное значение ключа, или В поисках «последних» записей

Reading time2 min
Views9.9K

Сегодняшняя задача вполне традиционна для любых учетных систем - поиск записей, содержащих максимальное значение по каждому из ключей. Что-то вроде "покажи мне последний заказ по каждому из клиентов", если переводить в прикладную область.

Кажется, что тут и споткнуться-то негде в реализации - но все оказывается совсем не тривиально.

Читать далее
Total votes 24: ↑22 and ↓2+20
Comments42

PostgreSQL в «Тензоре» — публикации за год (#3)

Reading time3 min
Views3.5K

Под занавес уходящего года предлагаю традиционно вспомнить, про какие интересные возможности и особенности работы с PostgreSQL мы рассказали в нашем блоге.

Если не видели дайджест за прошлый год — время наверстать упущенное!

Читать далее
Total votes 6: ↑6 and ↓0+6
Comments0

DBA: хранение списков — таблица, массив, строка?

Reading time4 min
Views13K

Достаточно часто при проектировании схемы БД возникает задача сохранить по основной сущности некоторый набор простых второстепенных данных.

Например, это могут быть ФИО сотрудников, принимающих участие во встрече, список приложенных к сообщению файлов или перечень отгружаемых по документу позиций.

Во всех этих случаях мы заранее понимаем, что список этот меняется редко и ни индексировать эти данные, ни искать по ним, ни извлекать отдельно от основной сущности (встречи, сообщения или документа), мы не захотим.

Давайте посмотрим, какие варианты хранения таких данных мы можем использовать в PostgreSQL, и какой из них окажется в разы более эффективным.

Читать далее
Total votes 22: ↑18 and ↓4+14
Comments21

PostgreSQL Antipatterns: простой(?) INSERT… VALUES

Reading time3 min
Views16K

Представим, что у вас есть некоторая табличка статистики, куда вы периодически скидываете таймстамп последнего "текущего" состояния в паре координат - например, (ID организации, ID сотрудника).

Как больно наступить на грабли в совсем простом, казалось бы, запросе?

Читать далее
Total votes 43: ↑39 and ↓4+35
Comments32
1
23 ...

Information

Rating
157-th
Location
Ярославль, Ярославская обл., Россия
Works in
Date of birth
Registered
Activity