В PL/SQL
Ловит любые ошибки
Если пихать это везде и не пробрасывать ошибку дальше, можно спокойно пропустить неожиданные проблемы
Поэтому компилятор кидает предупреждение PLW-6009
Если в кастомном логгере ты все-таки пробрасываешь ошибку дальше, то используй
чтобы отключить это предупреждение
👉 @SQLPortal
EXCEPTION WHEN OTHERS THEN
Ловит любые ошибки
Если пихать это везде и не пробрасывать ошибку дальше, можно спокойно пропустить неожиданные проблемы
Поэтому компилятор кидает предупреждение PLW-6009
Если в кастомном логгере ты все-таки пробрасываешь ошибку дальше, то используй
PRAGMA SUPPRESSES_WARNING_6009
чтобы отключить это предупреждение
ALTER SESSION SET PLSQL_WARNINGS='ENABLE:(6009)';
CREATE PROCEDURE logging ( err VARCHAR2 ) AS
PRAGMA SUPPRESSES_WARNING_6009(logging);
BEGIN
-- логирование ошибки / повторный RAISE
END;
/
CREATE PROCEDURE do_stuff AS
BEGIN
-- какая-то логика
EXCEPTION
WHEN OTHERS THEN logging('Error details');
END;
/
-- Нет ошибок.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍5❤1
В Postgres есть десятки типов индексов, заточенных под разные типы данных и задачи. В целом их можно разделить на две категории:
По назначению или области применения (что именно индексируем). Здесь мы решаем, какие колонки или данные таблицы индексировать и нужно ли применять функцию к индексируемым значениям. Примеры: индекс по одной колонке, составной (composite), покрывающий (covering), частичный (partial) и функциональный/выражения (functional/expression) индекс.
По внутренней структуре и методу доступа (как индексируем). Эта категория основана на том, как индекс хранит данные под капотом и как СУБД к ним обращается. Примеры: B-tree, hash, GIN, RUM, GiST, SP-GiST, BRIN, HNSW и IVFFlat.
Когда ты выполняешь CREATE INDEX, ты всегда выбираешь тип индекса из первой категории (что индексировать). Выбор структуры (как индексировать) — опционален. Если ничего не указать, Postgres по умолчанию использует B-tree.
👉 @SQLPortal
По назначению или области применения (что именно индексируем). Здесь мы решаем, какие колонки или данные таблицы индексировать и нужно ли применять функцию к индексируемым значениям. Примеры: индекс по одной колонке, составной (composite), покрывающий (covering), частичный (partial) и функциональный/выражения (functional/expression) индекс.
По внутренней структуре и методу доступа (как индексируем). Эта категория основана на том, как индекс хранит данные под капотом и как СУБД к ним обращается. Примеры: B-tree, hash, GIN, RUM, GiST, SP-GiST, BRIN, HNSW и IVFFlat.
Когда ты выполняешь CREATE INDEX, ты всегда выбираешь тип индекса из первой категории (что индексировать). Выбор структуры (как индексировать) — опционален. Если ничего не указать, Postgres по умолчанию использует B-tree.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Postgres UNION vs UNION ALL
Оба оператора объединяют результаты двух или более SELECT запросов в один набор данных.
UNION удаляет дубликаты
UNION ALL оставляет дубликаты
Если ты уверен что дубликатов нет или они тебя не волнуют, UNION ALL будет быстрее, потому что пропускает проверку на повторяющиеся строки.
👉 @SQLPortal
Оба оператора объединяют результаты двух или более SELECT запросов в один набор данных.
UNION удаляет дубликаты
UNION ALL оставляет дубликаты
Если ты уверен что дубликатов нет или они тебя не волнуют, UNION ALL будет быстрее, потому что пропускает проверку на повторяющиеся строки.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5👀2🔥1
Мы уже знаем причину худшего сбоя Cloudflare с 2019 года — криво спроектированный SQL-запрос.
После изменения прав он начал дублировать данные.
Внутренний файл разросся до безумных размеров, уронил тысячи серверов и положил половину интернета.
Выглядело как масштабная атака, но это оказалась обычная ошибка в конфигурации, которую никто не заметил до того момента, пока всё не бахнуло.
👉 @SQLPortal
После изменения прав он начал дублировать данные.
Внутренний файл разросся до безумных размеров, уронил тысячи серверов и положил половину интернета.
Выглядело как масштабная атака, но это оказалась обычная ошибка в конфигурации, которую никто не заметил до того момента, пока всё не бахнуло.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8👍2
Postgres использует TOAST для хранения больших переменных значений вроде JSONB и TEXT.
Использование TOAST влияет на производительность, так что нужно понимать компромиссы.
Каждая строка хранится в файле, который разбит на страницы по 8 KB. Обычно одна страница может держать десятки или сотни строк, но это зависит от количества и типов колонок.
Широкие таблицы могут иметь строки размером в несколько килобайт. Если строка превышает порог (например, около 2 KB), Postgres решает использовать The Oversized-Attribute Storage Technique (TOAST), а не запихивать все данные в основной файл таблицы.
TOAST применяет сжатие и перенос больших значений в отдельную таблицу — TOAST-таблицу. У нее всего три колонки: chunk_id, chunk_seq и chunk_data. Большие значения режутся на чанки, эти чанки кладутся в отдельную таблицу, а в основной таблице остается только ссылка на них.
Это позволяет держать строки в основном файле компактными. Минус в том, что при обращении к таким данным нужно делать дополнительные I/O на другую таблицу (и возможно тратить CPU на декомпрессию). Гибкость в работе с большими полями удобна, но может ударить по перформансу по сравнению с хранением всего в основной таблице или нормализацией данных в компактные фиксированные колонки.
👉 @SQLPortal
Использование TOAST влияет на производительность, так что нужно понимать компромиссы.
Каждая строка хранится в файле, который разбит на страницы по 8 KB. Обычно одна страница может держать десятки или сотни строк, но это зависит от количества и типов колонок.
Широкие таблицы могут иметь строки размером в несколько килобайт. Если строка превышает порог (например, около 2 KB), Postgres решает использовать The Oversized-Attribute Storage Technique (TOAST), а не запихивать все данные в основной файл таблицы.
TOAST применяет сжатие и перенос больших значений в отдельную таблицу — TOAST-таблицу. У нее всего три колонки: chunk_id, chunk_seq и chunk_data. Большие значения режутся на чанки, эти чанки кладутся в отдельную таблицу, а в основной таблице остается только ссылка на них.
Это позволяет держать строки в основном файле компактными. Минус в том, что при обращении к таким данным нужно делать дополнительные I/O на другую таблицу (и возможно тратить CPU на декомпрессию). Гибкость в работе с большими полями удобна, но может ударить по перформансу по сравнению с хранением всего в основной таблице или нормализацией данных в компактные фиксированные колонки.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
• Как переносили сотни миллионов записей без даунтайма и потерь;
• Почему отказались от распределённых транзакций и как обеспечили согласованность данных;
• Как выкатывали изменения поэтапно — с возможностью отката в любой момент.
Всё это — под высокой нагрузкой, без влияния на пользователей и с полной гарантией доступности сервиса.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍1🔥1
Forwarded from IT Portal
This media is not supported in your browser
VIEW IN TELEGRAM
Дружеское напоминание: у PostgreSQL есть официальное расширение для VS Code
Оно заметно упрощает работу с Postgres и позволяет взаимодействовать с базой данных прямо в редакторе
Основные плюшки:
Ссылка на расширение: PostgreSQL for VS Code
@IT_Portal
Оно заметно упрощает работу с Postgres и позволяет взаимодействовать с базой данных прямо в редакторе
Основные плюшки:
- Встроенная визуализация схемы БД
- Общаться с базой данных через агентов
- Смотреть метрики и аналитику
- Быстрый запуск PostgreSQL в Docker
- IntelliSense с контекстом БД (автокомплит, форматирование, подсветка синтаксиса)
…и многое другое
Ссылка на расширение: PostgreSQL for VS Code
@IT_Portal
❤8👍5
В Postgres count(*) работает так же эффективно, как count(1). Как так? Давай разберём планы выполнения, как на картинках.
1. SELECT count(order_id)
Каждая выбранная строка, подходящая под условие, имеет размер 4 байта (width=4 в плане). Это размер колонки order_id, 32-битное целое.
2. SELECT count(1)
Известная фишка во многих СУБД. База просто находит строки и считает их. Размер строки тут 0 (width=0), потому что в функцию передается константа. Константа может быть 1, 10, 666 или любое число — пофиг.
3. SELECT count(*)
В Postgres для этого случая есть особая оптимизация. Несмотря на звёздочку, база не тянет все колонки. Размер строки тоже 0 (width=0), так что никаких лишних данных не читается.
Вывод: спокойно пользуйся SELECT count(*) в Postgres. Оптимизация уже под капотом
👉 @SQLPortal
1. SELECT count(order_id)
Каждая выбранная строка, подходящая под условие, имеет размер 4 байта (width=4 в плане). Это размер колонки order_id, 32-битное целое.
2. SELECT count(1)
Известная фишка во многих СУБД. База просто находит строки и считает их. Размер строки тут 0 (width=0), потому что в функцию передается константа. Константа может быть 1, 10, 666 или любое число — пофиг.
3. SELECT count(*)
В Postgres для этого случая есть особая оптимизация. Несмотря на звёздочку, база не тянет все колонки. Размер строки тоже 0 (width=0), так что никаких лишних данных не читается.
Вывод: спокойно пользуйся SELECT count(*) в Postgres. Оптимизация уже под капотом
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9