Онлайн-опросы неизменно показывают — всех нас очень интересуют две вещи: а) как писать наиболее эффективные SQL-запросы, б) как «читать» такие запросы, а точнее, как понимать, что именно делает или будет делать СУБД при их выполнении.
Эти две неразрывно связанные друг с другом темы чрезвычайно обширны, SQL-искусству можно (и нужно) учиться годами. Во время нашей очередной встречи в прямом эфире мы затронем некоторые аспекты обеих.
ЧАСТЬ 1: EXPLAIN
Алексей Ермаков. Как читать и интерпретировать вывод команды EXPLAIN
Команда EXPLAIN — основной инструмент анализа запросов, позволяющий разобраться, каким образом запрос будет выполняться и как можно его ускорить. Для сложных запросов вывод может быть довольно громоздким и его становится сложно читать. Я расскажу, из каких частей состоит план запроса, на какие «маркеры» в нём следует обращать внимание в первую очередь и как на это реагировать.
ЧАСТЬ 2: ADVANCED SQL
Николай Самохвалов. SQL современный и «продвинутый»
«Я не волшебник, я только учусь». Продвинутому SQL нас постоянно учат такие видные гуру как Markus Winand и Макс Богук. Рекурсивные CTE, LATERAL JOIN, виртуозная работа с массивами и строками, window functions и прочие модные штучки, которые помогут вам в дрессировке вашего Постгреса, — я постараюсь сделать хороший обзор, а если вдруг тема покажется интересной, то в следующих сеансах группового Постгреса мы обязательно пригласим настоящих гуру :)
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...Ontico
Механизм секционирования в Postgres имеет ряд ограничений, которые не позволяют использовать концепцию секционирования в полной мере. Среди таких ограничений можно выделить неэффективность планирования запросов для секционированных таблиц (линейный рост времени планирования при увеличении количества секций), отсутствие HASH-секционирования, необходимость ручного управления секциями.
В нашем докладе мы расскажем про расширение pg_pathman, которое позволяет обойти эти ограничения. pg_pathman реализует RANGE и HASH секционирования с логарифмическим и константным временами планирования соответственно. В pg_pathman поддерживается определение секции на этапе выполнения, конкурентное секционирование.
pg_pathman долго находился в стадии beta-тестирования, но теперь мы рады, наконец, сообщить о релизе 1.0. В докладе мы расскажем как про детали внутреннего устройства, так и про приёмы практического использования.
Техносфера Mail.ru Group, МГУ им. М.В. Ломоносова.
Курс "Методы распределенной обработки больших объемов данных в Hadoop"
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9rPxMIgPri9YnOpvyDAL9HD
СУБД 2013 Лекция №8 "Конфигурирование базы данных"Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №8 "Конфигурирование базы данных". Лектор - Павел Щербинин.
Сначала объясняются основы конфигурирования и общие принципы настройки. Далее рассказывается об области видимости, о настройке использования памяти, обсуждается размер блока ключей key_cache_block_size. Рассматривается устройство и использование кэша InnoDB, а также кэшей потоков и таблиц. Затем говорится об особенностях ввода/вывода в InnoDB. Далее рассказывается о табличном пространстве, оптимизации файловой сортировки, переменных состояния. Финальная часть лекции посвящена репликации: настройка, синхронизация, топология, планирование пропускной способности, администрирование и обслуживание, проблемы и их решения.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...Ontico
Механизм секционирования в Postgres имеет ряд ограничений, которые не позволяют использовать концепцию секционирования в полной мере. Среди таких ограничений можно выделить неэффективность планирования запросов для секционированных таблиц (линейный рост времени планирования при увеличении количества секций), отсутствие HASH-секционирования, необходимость ручного управления секциями.
В нашем докладе мы расскажем про расширение pg_pathman, которое позволяет обойти эти ограничения. pg_pathman реализует RANGE и HASH секционирования с логарифмическим и константным временами планирования соответственно. В pg_pathman поддерживается определение секции на этапе выполнения, конкурентное секционирование.
pg_pathman долго находился в стадии beta-тестирования, но теперь мы рады, наконец, сообщить о релизе 1.0. В докладе мы расскажем как про детали внутреннего устройства, так и про приёмы практического использования.
Техносфера Mail.ru Group, МГУ им. М.В. Ломоносова.
Курс "Методы распределенной обработки больших объемов данных в Hadoop"
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9rPxMIgPri9YnOpvyDAL9HD
СУБД 2013 Лекция №8 "Конфигурирование базы данных"Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №8 "Конфигурирование базы данных". Лектор - Павел Щербинин.
Сначала объясняются основы конфигурирования и общие принципы настройки. Далее рассказывается об области видимости, о настройке использования памяти, обсуждается размер блока ключей key_cache_block_size. Рассматривается устройство и использование кэша InnoDB, а также кэшей потоков и таблиц. Затем говорится об особенностях ввода/вывода в InnoDB. Далее рассказывается о табличном пространстве, оптимизации файловой сортировки, переменных состояния. Финальная часть лекции посвящена репликации: настройка, синхронизация, топология, планирование пропускной способности, администрирование и обслуживание, проблемы и их решения.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №9 "Безопасность баз данных". Лектор - Павел Щербинин.
Открывается лекция рассказом о резервном копировании (о логических и физических резервных копиях, о выборе данных для копирования). Затем определяется терминология для обсуждения дальнейших вопросов. После этого рассматриваются основы учётных записей: таблицы доступа, привилегии, виды записей. Обсуждаются SQL-injection, список смежных вершин (Adjacency Set), вложенное множество (Nested Set), материализованный путь (Materialized Path) и комбинированный подход.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №5 "Определение узких мест". Лектор - Павел Щербинин.
Вначале рассказывается о подсистемах хранения: MyISAM, InnoDB, Memory, о критериях выбора подсистем хранения, приводятся практические примеры. Затем обсуждается тема индексирования (B-tree, хеш-индексы) и EXPLAIN (столбцы id, table, possible_keys, key, key_len).
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-запросы". Лектор - Павел Щербинин.
Лекция открывается рассказом о том, что такое профилирование запроса, каковы его этапы выполнения в MySQL. Рассказывается о том, как планировать запрос, как осуществляется протоколирование запросов, как собирается статистика. Объясняются основы индексирования, подробно обсуждаются стратегии индексирования для достижения высокой производительности: изоляция столбца, кластерные индексы (преимущества и недостатки), размещение данных в MyISAM и InnoDB, покрывающие индексы. Далее затрагивается тема нормализации и денормализации, а также таблиц счётчиков. В завершении рассказывается о версионировании схемы БД: о методах инкрементных изменений, идемпотентных изменений, уподобления структуры БД исходному коду.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Техносфера Mail.ru Group, МГУ им. М.В. Ломоносова.
Курс "Методы распределенной обработки больших объемов данных в Hadoop"
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9rPxMIgPri9YnOpvyDAL9HD
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №7 "Оптимизация запросов и индексирование". Лектор - Павел Щербинин.
Вначале рассказывается об оптимизации доступа к данным, о декомпозиции соединения и состоянии запроса. Далее идёт большой блок, посвящённый оптимизатору запросов (изменение порядка соединения, применение алгебраических правил эквивалентности, оптимизации COUNT(), MIN(), MAX(), вычисление и свертка константных выражений, покрывающие индексы, оптимизация подзапросов, раннее завершение, сравнение по списку IN() и распространение равенства). Затем последовательно рассматриваются такие вещи, как соединение (JOIN) в MySQL, оптимизатор сортировки, коррелированные подзапросы, слияние и непоследовательный просмотр индексов, функции SELECT & UPDATE, COUNT(). После этого рассказывается об оптимизации запросов с помощью JOIN, GROUP BY, DISTINCT и LIMIT со смещением. В конце лекции даётся информация о кэшировании запросов, объединённых таблицах и секционировании.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных". Лекция №4 "Расширенные возможности работы с базами данных. Триггеры и хранимые процедуры"
Лектор - Павел Щербинин.
Первая часть лекции посвящена хранимым процедурам (использование, примеры кода, аспекты безопасности при использовании хранимых процедур): LOOP, REPEAT, WHILE, HANDLER, курсоры, EXECUTE. Во второй части рассказывается о триггерах: BEFORE, AFTER, INSTEAD OF, о специальных таблицах inserted, updated и deleted, об использовании триггеров для поддержания целостности и бизнес-логики, о проблемах при использовании триггеров, приводятся примеры кода. В завершающей части лекции обсуждаются вопросы, связанные с транзакциями: концепция A.C.I.D.; уровни изоляции ANSI/ISO (SET TRANSACTION ISOLATION LEVEL); взаимовлияние транзакций и проблемы lost update, dirty read, non-repeatable read и phantom read; технология MVCC (контроль версионирования конкуренции); конкуренция; параллельность и согласованность.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
СУБД PostgreSQL ИЗ ДИСТРИБУТИВА ОПЕРАЦИОННОЙ СИСТЕМЫ СПЕЦИАЛЬНОГО НАЗНАЧЕНИЯ ...Michael Oreshin
СУБД PostgreSQL
ИЗ ДИСТРИБУТИВА ОПЕРАЦИОННОЙ СИСТЕМЫ
СПЕЦИАЛЬНОГО НАЗНАЧЕНИЯ
"Astra Linux Special Edition"
ДЛЯ ОБРАБОТКИ СВЕДЕНИЙ,
СОСТАВЛЯЮЩИХ ГОСУДАРСТВЕННУЮ ТАЙНУ
You know that person everybody comes to when the shit hits the fan and that bug is not going to fix itself? Want to become one? Come to learn about all the skills you'll need when your application freezes in production, leaks memory like crazy or dies under load in fifteen seconds
Производительность параметрического поиска на основе опенсорс-платформыYandex
В докладе рассматриваются особенности системы параметрического поиска, построенной на базе опенсорс-плаформы Apache Solr. Речь пойдёт о проблемах производительности такой системы и некоторых методах их решения — в том числе о применении различных способов построения запросов для уменьшения времени ответа системы.
Современному хайлоду - современные решения: MySQL 8.0 и улучшения PerconaSveta Smirnova
MySQL всегда использовали под высокой нагрузкой. Недаром эта база была и остаётся самым популярным бэкэндом для web. Однако наши представления о хайлоде с каждым годом расширяются. Большая скорость передачи данных -> больше устройств с подключением к интернет -> больше пользователей -> больше данных.
Задачи, стоящие перед разработчиками MySQL, с каждым годом усложняются.
В этом докладе я расскажу как менялись сценарии использования MySQL за [почти] 25 лет её истории и что делали инженеры, чтобы MySQL оставалась актуальной. Мы затронем такие темы, как работа с большим количеством активных соединений и высокими объёмами данных. Я покажу насколько современные версии лучше справляются с возросшими нагрузками.
Я надеюсь, что после моего доклада те слушатели, которые используют старые версии, захотят обновиться и те, кто уже обновились, узнают как использовать современный MySQL на полную мощность.
Прочитана на конференции OST 2020: https://ostconf.com/materials/2857#2857
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Ontico
Вы взяли ваш любимый фреймворк™ и быстро запустили крутой проект, который раскручивается, приносит деньги и требует быстрого развития, чтобы оставить конкурентов далеко позади.
В один далеко не прекрасный момент вы понимаете, что корень всех зол - медленное время ответа базы данных, а ваш админ зло смотрит на разработчиков красными от бессонницы глазами и ругается на безумные запросы, которые генерирует ORM. Тот самый ORM, который позволил вам так быстро запустить ваш замечательный проект.
Знакомо? Тогда вам будет интересно послушать, как заставить вашу базу данных работать прямо сейчас. А именно:
- какое место в общей производительности базы данных занимает оптимизация запросов?
- когда прекращать “крутить гайки” и заниматься медленными запросами?
- что такое медленный запрос и когда их надо начинать оптимизировать?
- как оптимизировать?
- EXPLAIN, EXPLAIN ANALYZE - как читать и на что обращать внимание?
- как работает оптимизатор запросов PostgreSQL и где могут быть узкие места?
- для чего нужны и для чего не нужны индексы, методики индексирования, и как быть уверенным, что ваш индекс правильно используется?
- какие запросы не будут работать быстро никогда, и как с этим жить?
- ошибается ли оптимизатор и, если да, то почему и как его в таком случае призвать к порядку?
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №9 "Безопасность баз данных". Лектор - Павел Щербинин.
Открывается лекция рассказом о резервном копировании (о логических и физических резервных копиях, о выборе данных для копирования). Затем определяется терминология для обсуждения дальнейших вопросов. После этого рассматриваются основы учётных записей: таблицы доступа, привилегии, виды записей. Обсуждаются SQL-injection, список смежных вершин (Adjacency Set), вложенное множество (Nested Set), материализованный путь (Materialized Path) и комбинированный подход.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №5 "Определение узких мест". Лектор - Павел Щербинин.
Вначале рассказывается о подсистемах хранения: MyISAM, InnoDB, Memory, о критериях выбора подсистем хранения, приводятся практические примеры. Затем обсуждается тема индексирования (B-tree, хеш-индексы) и EXPLAIN (столбцы id, table, possible_keys, key, key_len).
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-запросы". Лектор - Павел Щербинин.
Лекция открывается рассказом о том, что такое профилирование запроса, каковы его этапы выполнения в MySQL. Рассказывается о том, как планировать запрос, как осуществляется протоколирование запросов, как собирается статистика. Объясняются основы индексирования, подробно обсуждаются стратегии индексирования для достижения высокой производительности: изоляция столбца, кластерные индексы (преимущества и недостатки), размещение данных в MyISAM и InnoDB, покрывающие индексы. Далее затрагивается тема нормализации и денормализации, а также таблиц счётчиков. В завершении рассказывается о версионировании схемы БД: о методах инкрементных изменений, идемпотентных изменений, уподобления структуры БД исходному коду.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
Техносфера Mail.ru Group, МГУ им. М.В. Ломоносова.
Курс "Методы распределенной обработки больших объемов данных в Hadoop"
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9rPxMIgPri9YnOpvyDAL9HD
СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных".
Лекция №7 "Оптимизация запросов и индексирование". Лектор - Павел Щербинин.
Вначале рассказывается об оптимизации доступа к данным, о декомпозиции соединения и состоянии запроса. Далее идёт большой блок, посвящённый оптимизатору запросов (изменение порядка соединения, применение алгебраических правил эквивалентности, оптимизации COUNT(), MIN(), MAX(), вычисление и свертка константных выражений, покрывающие индексы, оптимизация подзапросов, раннее завершение, сравнение по списку IN() и распространение равенства). Затем последовательно рассматриваются такие вещи, как соединение (JOIN) в MySQL, оптимизатор сортировки, коррелированные подзапросы, слияние и непоследовательный просмотр индексов, функции SELECT & UPDATE, COUNT(). После этого рассказывается об оптимизации запросов с помощью JOIN, GROUP BY, DISTINCT и LIMIT со смещением. В конце лекции даётся информация о кэшировании запросов, объединённых таблицах и секционировании.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
СУБД 2013 Лекция №4 "Расширенные возможности работы с базами данных. Триггеры...Technopark
Технопарк Mail.ru Group, МГТУ им. Н.Э. Баумана. Курс "Базы данных". Лекция №4 "Расширенные возможности работы с базами данных. Триггеры и хранимые процедуры"
Лектор - Павел Щербинин.
Первая часть лекции посвящена хранимым процедурам (использование, примеры кода, аспекты безопасности при использовании хранимых процедур): LOOP, REPEAT, WHILE, HANDLER, курсоры, EXECUTE. Во второй части рассказывается о триггерах: BEFORE, AFTER, INSTEAD OF, о специальных таблицах inserted, updated и deleted, об использовании триггеров для поддержания целостности и бизнес-логики, о проблемах при использовании триггеров, приводятся примеры кода. В завершающей части лекции обсуждаются вопросы, связанные с транзакциями: концепция A.C.I.D.; уровни изоляции ANSI/ISO (SET TRANSACTION ISOLATION LEVEL); взаимовлияние транзакций и проблемы lost update, dirty read, non-repeatable read и phantom read; технология MVCC (контроль версионирования конкуренции); конкуренция; параллельность и согласованность.
Видео лекции курса https://www.youtube.com/playlist?list=PLrCZzMib1e9obOz5K695ugYuiOOCBciEi
СУБД PostgreSQL ИЗ ДИСТРИБУТИВА ОПЕРАЦИОННОЙ СИСТЕМЫ СПЕЦИАЛЬНОГО НАЗНАЧЕНИЯ ...Michael Oreshin
СУБД PostgreSQL
ИЗ ДИСТРИБУТИВА ОПЕРАЦИОННОЙ СИСТЕМЫ
СПЕЦИАЛЬНОГО НАЗНАЧЕНИЯ
"Astra Linux Special Edition"
ДЛЯ ОБРАБОТКИ СВЕДЕНИЙ,
СОСТАВЛЯЮЩИХ ГОСУДАРСТВЕННУЮ ТАЙНУ
You know that person everybody comes to when the shit hits the fan and that bug is not going to fix itself? Want to become one? Come to learn about all the skills you'll need when your application freezes in production, leaks memory like crazy or dies under load in fifteen seconds
Производительность параметрического поиска на основе опенсорс-платформыYandex
В докладе рассматриваются особенности системы параметрического поиска, построенной на базе опенсорс-плаформы Apache Solr. Речь пойдёт о проблемах производительности такой системы и некоторых методах их решения — в том числе о применении различных способов построения запросов для уменьшения времени ответа системы.
Современному хайлоду - современные решения: MySQL 8.0 и улучшения PerconaSveta Smirnova
MySQL всегда использовали под высокой нагрузкой. Недаром эта база была и остаётся самым популярным бэкэндом для web. Однако наши представления о хайлоде с каждым годом расширяются. Большая скорость передачи данных -> больше устройств с подключением к интернет -> больше пользователей -> больше данных.
Задачи, стоящие перед разработчиками MySQL, с каждым годом усложняются.
В этом докладе я расскажу как менялись сценарии использования MySQL за [почти] 25 лет её истории и что делали инженеры, чтобы MySQL оставалась актуальной. Мы затронем такие темы, как работа с большим количеством активных соединений и высокими объёмами данных. Я покажу насколько современные версии лучше справляются с возросшими нагрузками.
Я надеюсь, что после моего доклада те слушатели, которые используют старые версии, захотят обновиться и те, кто уже обновились, узнают как использовать современный MySQL на полную мощность.
Прочитана на конференции OST 2020: https://ostconf.com/materials/2857#2857
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Ontico
Вы взяли ваш любимый фреймворк™ и быстро запустили крутой проект, который раскручивается, приносит деньги и требует быстрого развития, чтобы оставить конкурентов далеко позади.
В один далеко не прекрасный момент вы понимаете, что корень всех зол - медленное время ответа базы данных, а ваш админ зло смотрит на разработчиков красными от бессонницы глазами и ругается на безумные запросы, которые генерирует ORM. Тот самый ORM, который позволил вам так быстро запустить ваш замечательный проект.
Знакомо? Тогда вам будет интересно послушать, как заставить вашу базу данных работать прямо сейчас. А именно:
- какое место в общей производительности базы данных занимает оптимизация запросов?
- когда прекращать “крутить гайки” и заниматься медленными запросами?
- что такое медленный запрос и когда их надо начинать оптимизировать?
- как оптимизировать?
- EXPLAIN, EXPLAIN ANALYZE - как читать и на что обращать внимание?
- как работает оптимизатор запросов PostgreSQL и где могут быть узкие места?
- для чего нужны и для чего не нужны индексы, методики индексирования, и как быть уверенным, что ваш индекс правильно используется?
- какие запросы не будут работать быстро никогда, и как с этим жить?
- ошибается ли оптимизатор и, если да, то почему и как его в таком случае призвать к порядку?
Доклад от Parallels:
Методики тестировния производительности database-centric приложений
Описание: При работе над сложными продуктами в database-centric приложениях изменения в коде и тем более в SQL запросах к базе данных могут приводить к неожиданным падениям производительности или же деградации производительности приложения с ростом размера базы данных. Поэтому важно уметь как можно быстрее отлавливать и исправлять причины таких деградаций.
Доклад о том, как устроен процесс мониторинга производительности продукта автоматизации хостинга и облачных сервисов Parallels Automation, для которого определяющим фактором является производительность базы данных.
Компания покажет, как анализирует планы исполнения SQL запросов внутри PostgreSQL, как проверяет насколько быстро и эффективно в целом работают SQL запросы, как определяет стратегию дальнейшей оптимизации.
Why do we need ORM? The difference between ActiveRecord and DataMapper patterns. The practical appliance of Iterative deepening depth-first search algo for topological sort of ORM relations.
Review of Cycle ORM and it features.
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...Nikolay Samokhvalov
Администрирование баз данных в будущем будет полностью автоматизировано. Это уже так для базовых операций DBA: поднятие инстансов, бэкапы, управление репликацией, failover — мы наблюдаем это по бурному развитию облачных «управляемых» СУБД (AWS RDS, Google Cloud SQL и десятков игроков поменьше), работе над k8s-оператором для Postgres и MySQL в ряде компаний, внедрению внутренних RDS-like DBaaS (database-as-a-service) решений внутри крупных организаций.
Но диагностика и оптимизация производительности баз данных сегодня всё ещё очень «ручные». Например, в Postgres: находим медленную группу запросов в pg_stat_statements, ищем конкретный пример (а то и «выдумываем» его на ходу), пробуем EXPLAIN ANALYZE сначала в dev/staging-окружении, где, как правило, данных не так много, а потом на prod'е... Подбираем индекс, убеждаемся, что он ускоряет (вроде бы) один SQL-запрос и — всё, отправляем в production. Метод «чик-чик и в production» должен остаться в прошлом! Как остались в прошлом развёртывание и настройка серверов и сервисов вручную.
Nancy CLI (https://github.com/postgres-ai/nancy) – открытый фреймворк для проведения экспериментов над базами данных PostgreSQL, позволяющий любому инженеру наладить системный подход к анализу и оптимизации производительности БД. Nancy поддерживает проведение экспериментов локально (на любом сервере) и удалённо на дешёвых высокопроизводительных спот-инстансах AWS EC2.
Без каких-либо специальных знаний, используя Nancy CLI, любой инженер может теперь:
- собрать подробную информацию о поведении «SQL-запросов с прода» на «клоне прода», но «не трогая прод» с целью выявления узких мест (на «проде» под нагрузкой включать обширную диагностику неразумно, а иногда и невозможно);
- проверить, как тот или иной индекс влияет на производительность SQL (в том числе, насколько он замедлит UPDATE'ы);
- подобрать оптимальные параметры настройки Postgres'а (пример: запустить в облаке проверку 100 вариантов default_statistics_target с подробным исследованием эффекта и анализом для каждой группы SQL-запросов);
- сравнить 2+ прогонов моделированной нагрузки на клоне реальной БД в различных условиях (разное оборудование, разные версии Postgres, разные настройки, разные наборы индексов).
В докладе мы также обсудим конкретные примеры внедрения метода автоматизации экспериментов над БД и Nancy CLI в ряд проектов различных компаний (БД до 2ТБ, hybrid workload, до 15k TPS) и трудности, которые пришлось преодолеть на пути:
1. Включение полного логирования запросов: когда это просто страх, а когда это действительно серьёзный стресс для сервера? Как быть, если диски «не тянут» полное логирование?
2. Вопросы безопасности: нужно ли давать доступ к экспериментальным узлам всем разработчикам или можно обойтись без этого? Обфускировать ли данные?
3. Как убедиться, что результаты эксперимента достоверны?
4. Как проводить эксперименты над терабайтной базой данных быстро?
5. Стоит ли включать Nancy в CI/CD-конвейер?
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данныхNikolay Samokhvalov
Shared_buffers = 25% – это много или мало? Или в самый раз? Как понять, подходит ли эта – довольно устаревшая – рекомендация в вашем конкретном случае?
Пришло время подойти к вопросу подбора параметров postgresql.conf "по-взрослому". Не с помощью слепых "автотюнеров" или устаревших советов из статей и блогов, а на основе:
строго выверенных экспериментов на БД, производимых автоматизированно, в больших количествах и в условиях, максимально приближенных к "боевым",
глубокого понимания особенностей работы СУБД и ОС.
Используя Nancy CLI (https://gitlab.com/postgres.ai/nancy), мы рассмотрим конкретный пример – пресловутые shared_buffers – в разных ситуациях, в разных проектах и попробуем разобраться, как же подобрать оптимальную настройку для нашей инфраструктуры, БД и нагрузки.
https://pgconf.ru/2019/242809
The Art of Database Experiments – PostgresConf Silicon Valley 2018 / San JoseNikolay Samokhvalov
Future database administration will be highly automated. Until then, we still live in a world where extensive manual interactions are required from a skilled DBA. This will change soon as more "autonomous databases" reach maturity and enter the production environment.
Postgres-specific monitoring tools and systems continue to improve, detecting and analyzing performance issues and bottlenecks in production databases. However, while these tools can detect current issues, they require highly-experienced DBAs to analyze and recommend mitigations.
In this session, the speaker will present the initial results of the POSTGRES.AI project – Nancy CLI, a unified way to manage automated database experiments. Nancy CLI is an automated database management framework based on well-known open-source projects and incorporating major open-source tools and Postgres modules: pgBadger, pg_stat_kcache, auto_explain, pgreplay, and others.
Originally developed with the goal to simulate various SQL query use cases in various environments and collect data to train ML models, Nancy CLI turned out to be very a universal framework that can play a crucial role in CI/CD pipelines in any company.
Using Nancy CLI, casual DBAs and any engineers can easily conduct automated experiments today, either on AWS EC2 Spot instances or on any other servers. All you need is to tell Nancy which database to use, specify workload (synthetic or "real", generated based on the Postgres logs), and what you want to test – say, check how a new index will affect all most expensive query groups from pg_stat_statements, or compare various values of "default_statistics_target". All the collected information with a very high level of confidence will give you understanding, how various queries and overall Postgres performance will be affected when you apply this change to production.
Nancy CLI, a unified way to manage automated database experiments. Nancy CLI is an automated database management framework based on well-known open-source projects and incorporating major open-source tools.
Using these tools, casual DBAs can conduct automated experiments today, either on AWS EC2 Spot instances or on any other servers. All you need is to tell Nancy which database to use, how to determine workloads and what you want to verify – say, check how some index will help, or compare various values of "default_statistics_target" for your database and your workload.
Everything else Nancy will do for you, in fully automated fashion, in the end presenting you detailed results for comparison.
#RuPostgresLive 4: как писать и читать сложные SQL-запросыNikolay Samokhvalov
Онлайн-опросы неизменно показывают — всех нас очень интересуют две вещи: а) как писать наиболее эффективные SQL-запросы, б) как «читать» такие запросы, а точнее, как понимать, что именно делает или будет делать СУБД при их выполнении.
Эти две неразрывно связанные друг с другом темы чрезвычайно обширны, SQL-искусству можно (и нужно) учиться годами. Во время нашей очередной встречи в прямом эфире мы затронем некоторые аспекты обеих.
ЧАСТЬ 1: EXPLAIN
Алексей Ермаков. Как читать и интерпретировать вывод команды EXPLAIN
Команда EXPLAIN — основной инструмент анализа запросов, позволяющий разобраться, каким образом запрос будет выполняться и как можно его ускорить. Для сложных запросов вывод может быть довольно громоздким и его становится сложно читать. Я расскажу, из каких частей состоит план запроса, на какие «маркеры» в нём следует обращать внимание в первую очередь и как на это реагировать.
ЧАСТЬ 2: ADVANCED SQL
Николай Самохвалов. SQL современный и «продвинутый»
«Я не волшебник, я только учусь». Продвинутому SQL нас постоянно учат такие видные гуру как Markus Winand и Макс Богук. Рекурсивные CTE, LATERAL JOIN, виртуозная работа с массивами и строками, window functions и прочие модные штучки, которые помогут вам в дрессировке вашего Постгреса, — я постараюсь сделать хороший обзор, а если вдруг тема покажется интересной, то в следующих сеансах группового Постгреса мы обязательно пригласим настоящих гуру :)
Database First! О распространённых ошибках использования РСУБДNikolay Samokhvalov
Мы обсудим несколько фундаментальных ситуаций использования РСУБД (каждая из которых неоднократно встречалась автору), попутно разбирая возможные ошибки:
- элементарная модификация данных;
- работа с датой, временем и временными зонами;
- проверка ограничений целостности;
- очередь заданий;
- пакетная работа с данными (например, удаление пачки записей в таблице);
- полнотекстовый поиск;
- относительно новые задачи (создание API, machine learning).
#RuPostges в Yandex, эпизод 3. Что же нового в PostgreSQL 9.6Nikolay Samokhvalov
Первый релиз-кандидат версии 9.6 вышел 1 сентября, а это значит, что совсем скоро будет полноценный релиз. Все вокруг уже успели обсудить новинки, и теперь уже стыдно ничего не знать о таких вещах, как параллелизация выполнения запросов, pushdown для FDW, мониторинг waitlocks, полнотекстовый поиск по фразам или магический \gexec в psql. Чтобы никому не приходилось краснеть, мы быстро пройдёмся по всем основным и интересным моментам версии 9.6.
A Lightning talk about Postgres in Russia and #PostgreSQLRussia, Nikolay Samokhvalov, includes 2016 CfPs inviting speakers to PgDay.ru, PgConf.ru and Highload.co convefereces
Владимир Бородин: Как спать спокойно - 2015.10.14 PostgreSQLRussia.org meetu...Nikolay Samokhvalov
More: http://PostgreSQLRussia.org
Доклад посвящён резервному хранению СУБД PostgreSQL. Мы поговорим о том, как устроено хранение данных на диске и организован WAL в PostgreSQL, какие есть средства для резервного копирования и восстановления данных. Обсудим, как перестать беспокоиться за свои данные и почему PostgreSQL славится своей надёжностью.
#PostgreSQLRussia 2015.09.15 - Николай Самохвалов - 5 главных особенностей Po...Nikolay Samokhvalov
Встречи сообщества http://PostgreSQLRussia.org -
Миграция из Oracle в Postgres. Встреча в компании CUSTIS.
План встречи:
19:00 Приветственная пицца, свободное общение.
19:20 Вступление. Рассказ о CUSTIS.
19:25 Николай Самохвалов. Коротко о PostgreSQL.
19:35 Максим Трегубов, CUSTIS. Миграция данных из Oracle в Postgres. Доклад о том, как мы для одного из заказчиков тестировали переход с СУБД Oracle на Postgres. Расскажем о выборе инструмента миграции данных, настройке тестовой среды и о полученных результатах. Также немного затронем модную тему DevOps и покажем роль Ansible в миграции данных.
20:10 Вячеслав Муравлев, CUSTIS. Data Access Layer как страховка при миграции СУБД. Для многих АС миграция с одной СУБД на другую сродни наступлению страхового случая «тотал» - необходимо переписать львиную долю кода. Подстраховаться от такого ущерба можно с помощью шаблона проектирования Data Access Layer (DAL). Мы расскажем как этот подход помог нам провести первый этап миграции АС одного из заказчиков с Oracle на PostgreSQL, рассмотрим инструментарий, обсудим применимость подхода на уровне предприятия.
20:30 Иван Кухарчук, ЯНДЕКС. Как можно сэкономить на лицензиях и снизить нагрузку на Oracle, переселив отчёты в PostgreSQL.
20:50 Завершение встречи, свободное общение.
Максим Трегубов, CUSTIS. Миграция данных из Oracle в Postgres. Доклад о том, как мы для одного из заказчиков тестировали переход с СУБД Oracle на Postgres. Расскажем о выборе инструмента миграции данных, настройке тестовой среды и о полученных результатах. Также немного затронем модную тему DevOps и покажем роль Ansible в миграции данных.
Три вызова реляционным СУБД и новый PostgreSQL - #PostgreSQLRussia семинар по...Nikolay Samokhvalov
Реляционной модели скоро исполнится полвека – это огромный срок для любой технологической индустрии, не говоря уже об ИТ. За прошедшие годы этой модели было брошено немало вызовов, оказавших немалое влияние на развитие реляционных СУБД. В докладе обсуждаются три главных вызова реляционной модели, включая и NoSQL. На основе многолетнего опыта использования PostgreSQL для создания социальных сетей, объединяющих многомиллионные аудитории, наглядно демонстрируется как эта СУБД реагировала на возникающие вызовы. Речь также пойдет о «трех китах» PostgreSQL, которые не дают этой системе превратиться в монстра и позволяют обогащаться функционалом, необходимым для создания современных высоконагруженных проектов. Особое внимание в докладе уделено новым типам данных, JSON и JSONB — их возможностям, способам индексирования, а также разбору имеющихся недостатков.
2014.12.23 Николай Самохвалов, Ещё раз о JSON(b) в PostgreSQL 9.4Nikolay Samokhvalov
Тип данных JSONb – это, пожалуй, самая яркая новинка PostgreSQL 9.4, который вышел 18 декабря 2014.
Уже немало докладов и статей посвящено этому типу данных, работе с ним и индексации. Но как правило, информация в них перегружена специфичными для PostgreSQL терминами.
Запутались в моделях данных? В том, какие индексы могут вам помочь ускорить вашу работу с СУБД?
Этот доклад помогает сложить паттерн. Он для тех, кто начал использовать PostgreSQL совсем недавно или только планирует работать с ним. В нём рассказано о месте PostgreSQL в современном мире СУБД, о борьбе различных моделей данных за место под солнцем на этом рынке и то, как это отразилось на развитие Postgres.
Помимо прочего, рассказывается о том, какие вообще бывают деревья, как они помогают ускорять базы данных и почему PostgreSQL — просто райский лес для деревьев самого разного типа :)
См. также видео: http://postgresmen.ru/meetup/2014-12-23-parallels
* приемы доступа к данным;
* прикладной класс работы с БД поверх PDO, особенности PDO;
* связки пуллов коннектов;
* API хранимых процедур;
* работа c распределенным хранилищем;
* RPC между базами на примере асинхронного геокодинга.
PostgreSQL Moscow Meetup - September 2014 - Ilya Kosmodemyansky
#RuPostgresLive 4: как писать и читать сложные SQL-запросы
1. Как читать и интерпретировать
вывод команды EXPLAIN ?
Алексей Ермаков
alexey.ermakov@dataegret.com
2. 2 Как ускорить запрос?
• “Очень долгий, очень пристальный и очень задумчивый взгляд” на
запрос
dataegret.com
3. 2 Как ускорить запрос?
• “Очень долгий, очень пристальный и очень задумчивый взгляд” на
запрос
• EXPLAIN – основной инструмент анализа запросов
dataegret.com
4. 3 Как ускорить запрос?
• EXPLAIN без параметров показывает план запроса, но не выполняет1
запрос и не показывает статистику выполнения запроса
1
на самом деле может выполнить immutable/stable хранимки, но ведь они у вас ничего
не меняют, правда?
dataegret.com
5. 4 План запроса #1
explain select * from posts join categories on posts.category_id = categories.id where
posts.rating < 15;
--------------------------------------------------------------------------------------------
Nested Loop (cost=0.43..16.47 rows=1 width=32)
-> Index Scan using posts_rating_idx on posts (cost=0.29..8.30 rows=1 width=28)
Index Cond: (rating < 15)
-> Index Only Scan using categories_pkey on categories (cost=0.14..8.16 rows=1 width=4)
Index Cond: (id = posts.category_id)
dataegret.com
6. 5 План запроса #2
explain select * from posts join categories on posts.category_id = categories.id where
posts.rating < 35;
Hash Join (cost=27.84..117.61 rows=601 width=32)
Hash Cond: (posts.category_id = categories.id)
-> Bitmap Heap Scan on posts (cost=12.94..94.46 rows=601 width=28)
Recheck Cond: (rating < 35)
-> Bitmap Index Scan on posts_rating_idx (cost=0.00..12.79 rows=601 width=0)
Index Cond: (rating < 35)
-> Hash (cost=13.64..13.64 rows=100 width=4)
-> Index Only Scan using categories_pkey on categories (cost=0.14..13.64 rows=100 width=4)
dataegret.com
7. 6 План запроса #2
explain select * from posts join categories on posts.category_id = categories.id where
posts.rating < 35;
Hash Join (cost=27.84..117.61 rows=601 width=32)
Hash Cond: (posts.category_id = categories.id)
-> Bitmap Heap Scan on posts (cost=12.94..94.46 rows=601 width=28)
Recheck Cond: (rating < 35)
-> Bitmap Index Scan on posts_rating_idx (cost=0.00..12.79 rows=601 width=0)
Index Cond: (rating < 35)
-> Hash (cost=13.64..13.64 rows=100 width=4)
-> Index Only Scan using categories_pkey on categories (cost=0.14..13.64 rows=100 width=4)
dataegret.com
8. 7 План запроса
• Это дерево
• Вышестоящие узлы запрашивают данные у нижестоящих
• План запроса не меняется по мере выполнения, даже если оказалось
что ожидания расходятся с реальностью на 6 порядков
• База не хранит историю неудачных или медленных планов запросов.
Так что, если если запрос получает неверный план - он будет
получать его воспроизводимо2
2
если не меняются настройки базы, распределение данных, размеры таблиц и
индексов, не используется geqo
dataegret.com
9. 8 Мы любим ORM
select website0_.websiteId as websiteI1_304_0_,
website0_.websiteTitleType as websiteT2_304_0_,
website0_.websiteUrl as websiteU3_304_0_,
website0_.websiteLocalArticlePath as websiteL4_304_0_,
... (еще 14кб текста)
from Website website0_ where website0_.websiteId=$1
dataegret.com
10. 8 Мы любим ORM
select website0_.websiteId as websiteI1_304_0_,
website0_.websiteTitleType as websiteT2_304_0_,
website0_.websiteUrl as websiteU3_304_0_,
website0_.websiteLocalArticlePath as websiteL4_304_0_,
... (еще 14кб текста)
from Website website0_ where website0_.websiteId=$1
• Иногда план запроса читать проще, нежели сам запрос
dataegret.com
11. 9 Виды элементарных операций
Методы извлечения данных
• seq scan – последовательное чтение таблицы
• index scan – random io (чтение индекса + чтение таблицы)
• index only scan – random io (чтение только3 индекса)
• bitmap index scan + bitmap heap scan – компромисс между seq
scan/index scan, возможность использования нескольких индексов в
OR/AND условиях
• CTE scan – чтение из CTE (блок WITH)
• function scan – чтение строк из функции
3
Возможно и чтение таблицы, зависит от состояния visibility map
dataegret.com
12. 10 Виды элементарных операций
Методы соединения данных
• nested loop – оптимален для небольших наборов данных
• hash join – оптимален для больших наборов данных
• merge join – оптимален для больших наборов данных, в случае, если
они отсортированы
dataegret.com
13. 11 Nested loop
for each outer row:
for each inner row:
if join condition is true:
output combined row
dataegret.com
14. 12 Виды элементарных операций
Методы обработки данных
• sort – сортирует данные в памяти или на диске, есть более быстрый
topN вариант
• limit – ограничивает выборку
• aggregate – используется в агрегирующих функциях
• hash aggregate – используется в группировках
• unique – отбрасывает дубликаты из отсортированных выборок
• gather – используется для объединения данных с различных
воркеров при одновременном выполнении
dataegret.com
15. 13 Характеристики каждой операции
explain select * from pg_database;
QUERY PLAN
-----------------------------------------------------------
Seq Scan on pg_database (cost=0.00..0.16 rows=6 width=271)
(1 row)
Seq Scan тип операции
on pg_database объект, с которым проводится операция
cost=0.00..0.16 стоимость операции (startup..total cost)
rows=6 ожидаемое число строк
width=271 средняя ширина строки в байтах
dataegret.com
16. 14 startup..total cost
explain select * from posts order by id limit 5;
QUERY PLAN
--------------------------------------------------------------------------------------
Limit (cost=0.29..0.46 rows=5 width=28)
-> Index Scan using posts_pkey on posts (cost=0.29..347.29 rows=10000 width=28)
(2 rows)
dataegret.com
17. 14 startup..total cost
explain select * from posts order by id limit 5;
QUERY PLAN
--------------------------------------------------------------------------------------
Limit (cost=0.29..0.46 rows=5 width=28)
-> Index Scan using posts_pkey on posts (cost=0.29..347.29 rows=10000 width=28)
(2 rows)
• 0.29 + (347.29 - 0.29)*5/10000 = 0.4635
dataegret.com
18. 15 rows*width
• rows*width у корневого узла дает примерный порядок объема
результата в байтах
• если запрос часто вызывается и при этом запрашивает большое
число данных – то легко можно забить сеть между базой и
приложением
• передача данных по сети может занимать большее время, чем время
выполнения запроса
• не всегда стоит запрашивать все поля, что есть, особенно если они
широкие и никак не используются
dataegret.com
19. 16 Опции команды EXPLAIN
EXPLAIN (ANALYZE,VERBOSE,COSTS,BUFFERS,TIMING4) select * from t1;
QUERY PLAN
-------------------------------------------------------------------
Seq Scan on public.t1 (cost=0.00..104424.80 rows=10000000 width=8)
(actual time=0.218..2316.688 rows=10000000 loops=1)
Output: f1, f2
Buffers: shared read=44248
I/O Timings: read=322.7145
Planning time: 0.024 ms
Execution time: 3852.588 ms
4
COSTS и TIMING опции включены по-умолчанию
5
I/O Timings отображается, когда track_io_timing включен
dataegret.com
20. 17 План запроса #3
Gather (cost=100.57..1338637.12 rows=2346550 width=1526) (actual time=4489.134..4855.942 rows=79061 loops=1)
Workers Planned: 4 Workers Launched: 4
-> Nested Loop (cost=0.57..1103882.12 rows=2346550 width=1526)
(actual time=4482.217..4810.097 rows=15812 loops=5)
-> Parallel Seq Scan on deferred_report r (cost=0.00..97294.45 rows=1345386 width=8)
(actual time=0.026..702.618 rows=1098890 loops=5)
Filter: (("timestamp" < ’2017-02-26 21:00:00’::timestamp without time zone) AND (proxy_id = 37) AND
Rows Removed by Filter: 2709566
-> Index Scan using transactions_pkey on transactions t (cost=0.57..0.74 rows=1 width=1526)
(actual time=0.004..0.004 rows=0 loops=5494451)
Index Cond: (id = r.tx_id)
Filter: (status = ’ok’::status)
Rows Removed by Filter: 1
Planning time: 0.736 ms
Execution time: 4861.460 ms
dataegret.com
21. 18 Filter
-> Parallel Seq Scan on deferred_report r (cost=0.00..97294.45 rows=1345386 width=8)
(actual time=0.026..702.618 rows=1098890 loops=5)
Filter: (("timestamp" < ’2017-02-26 21:00:00’::timestamp without time zone) AND (proxy_id = 37
Rows Removed by Filter: 2709566
• Оправдано ли использование seq scan в данном случае?
dataegret.com
22. 18 Filter
-> Parallel Seq Scan on deferred_report r (cost=0.00..97294.45 rows=1345386 width=8)
(actual time=0.026..702.618 rows=1098890 loops=5)
Filter: (("timestamp" < ’2017-02-26 21:00:00’::timestamp without time zone) AND (proxy_id = 37
Rows Removed by Filter: 2709566
• Оправдано ли использование seq scan в данном случае?
• worker извлек 1098890
1098890+2709566
≈ 28% строк
dataegret.com
23. 18 Filter
-> Parallel Seq Scan on deferred_report r (cost=0.00..97294.45 rows=1345386 width=8)
(actual time=0.026..702.618 rows=1098890 loops=5)
Filter: (("timestamp" < ’2017-02-26 21:00:00’::timestamp without time zone) AND (proxy_id = 37
Rows Removed by Filter: 2709566
• Оправдано ли использование seq scan в данном случае?
• worker извлек 1098890
1098890+2709566
≈ 28% строк
• вероятно да, bitmap index scan может и был бы быстрее, но в 9.6 его еще нельзя
распараллелить по воркерам
dataegret.com
24. 19 Filter
-> Index Scan using transactions_pkey on transactions t (cost=0.57..0.74 rows=1 width=1526)
(actual time=0.004..0.004 rows=0 loops=5494451)
Index Cond: (id = r.tx_id)
Filter: (status = ’ok’::status)
Rows Removed by Filter: 1
• Используется ли оптимальный индекс в данном случае?
dataegret.com
25. 19 Filter
-> Index Scan using transactions_pkey on transactions t (cost=0.57..0.74 rows=1 width=1526)
(actual time=0.004..0.004 rows=0 loops=5494451)
Index Cond: (id = r.tx_id)
Filter: (status = ’ok’::status)
Rows Removed by Filter: 1
• Используется ли оптимальный индекс в данном случае?
• Большинство строк отбрасываются по условию status = ‘ok’::status
dataegret.com
26. 19 Filter
-> Index Scan using transactions_pkey on transactions t (cost=0.57..0.74 rows=1 width=1526)
(actual time=0.004..0.004 rows=0 loops=5494451)
Index Cond: (id = r.tx_id)
Filter: (status = ’ok’::status)
Rows Removed by Filter: 1
• Используется ли оптимальный индекс в данном случае?
• Большинство строк отбрасываются по условию status = ‘ok’::status
• Вероятно нет, может быть тут более уместен индекс по (id, status) или частичный индекс по id
where status = ‘ok’
dataegret.com
29. 22 Filter
WHERE dispatch_time + INTERVAL ’1 hour’ > now()
WHERE (DATE(o.created) >= ’2017-03-23’ AND DATE(o.created) <= ’2017-04-21’)
• конструкции такого вида не могут использовать обычный индекс по соответствующему полю
• необходимо привести их к виду индексируемое_поле индексируемый_оператор выражение
dataegret.com
30. 23 Опция buffers
-> Index Only Scan using user_balance_id_type on user_balance ub (cost=0.00..0.56 rows=1 width=8)
(actual time=0.031..1.453 rows=1 loops=29721)
Index Cond: ((id = o.user_balance_id) AND (type = 1))
Heap Fetches: 7192482
Buffers: shared hit=7608576
• Что-то пошло не так...
dataegret.com
31. 23 Опция buffers
-> Index Only Scan using user_balance_id_type on user_balance ub (cost=0.00..0.56 rows=1 width=8)
(actual time=0.031..1.453 rows=1 loops=29721)
Index Cond: ((id = o.user_balance_id) AND (type = 1))
Heap Fetches: 7192482
Buffers: shared hit=7608576
• Что-то пошло не так...
• Читаем 7608576
29721
= 256 страниц, чтобы извлечь одну строку
dataegret.com
32. 23 Опция buffers
-> Index Only Scan using user_balance_id_type on user_balance ub (cost=0.00..0.56 rows=1 width=8)
(actual time=0.031..1.453 rows=1 loops=29721)
Index Cond: ((id = o.user_balance_id) AND (type = 1))
Heap Fetches: 7192482
Buffers: shared hit=7608576
• Что-то пошло не так...
• Читаем 7608576
29721
= 256 страниц, чтобы извлечь одну строку
• Вероятно, очень большой bloat в таблице/индексе
dataegret.com
33. 23 Опция buffers
-> Index Only Scan using user_balance_id_type on user_balance ub (cost=0.00..0.56 rows=1 width=8)
(actual time=0.031..1.453 rows=1 loops=29721)
Index Cond: ((id = o.user_balance_id) AND (type = 1))
Heap Fetches: 7192482
Buffers: shared hit=7608576
• Что-то пошло не так...
• Читаем 7608576
29721
= 256 страниц, чтобы извлечь одну строку
• Вероятно, очень большой bloat в таблице/индексе
• Длинные транзакции? Не справляется автовакуум?
dataegret.com
34. 23 Опция buffers
-> Index Only Scan using user_balance_id_type on user_balance ub (cost=0.00..0.56 rows=1 width=8)
(actual time=0.031..1.453 rows=1 loops=29721)
Index Cond: ((id = o.user_balance_id) AND (type = 1))
Heap Fetches: 7192482
Buffers: shared hit=7608576
• Что-то пошло не так...
• Читаем 7608576
29721
= 256 страниц, чтобы извлечь одну строку
• Вероятно, очень большой bloat в таблице/индексе
• Длинные транзакции? Не справляется автовакуум?
• Отстающая реплика с hot_standby_feedback = on !
dataegret.com
35. 24 I/O timings
-> Bitmap Heap Scan on delivery fi (cost=872967.27..4196621.37 rows=32425255 width=36)
(actual time=30842.138..37818.082 rows=6674571 loops=1)
Recheck Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <= ’2
Filter: ((NOT is_deleted) OR (qty > 0))
Rows Removed by Filter: 60545
Heap Blocks: exact=667323
Buffers: shared hit=47584 read=827816 dirtied=1 written=2292
I/O Timings: read=30152.376 write=42.134
-> Bitmap Index Scan on delivery_datetime_start_datetime_end_idx (cost=0.00..864860.96 rows=32514577 width=
Index Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <
Buffers: shared hit=80 read=207997
I/O Timings: read=27315.687
dataegret.com
36. 24 I/O timings
-> Bitmap Heap Scan on delivery fi (cost=872967.27..4196621.37 rows=32425255 width=36)
(actual time=30842.138..37818.082 rows=6674571 loops=1)
Recheck Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <= ’2
Filter: ((NOT is_deleted) OR (qty > 0))
Rows Removed by Filter: 60545
Heap Blocks: exact=667323
Buffers: shared hit=47584 read=827816 dirtied=1 written=2292
I/O Timings: read=30152.376 write=42.134
-> Bitmap Index Scan on delivery_datetime_start_datetime_end_idx (cost=0.00..864860.96 rows=32514577 width=
Index Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <
Buffers: shared hit=80 read=207997
I/O Timings: read=27315.687
• 30c из 37с ушло на чтение с диска
dataegret.com
37. 24 I/O timings
-> Bitmap Heap Scan on delivery fi (cost=872967.27..4196621.37 rows=32425255 width=36)
(actual time=30842.138..37818.082 rows=6674571 loops=1)
Recheck Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <= ’2
Filter: ((NOT is_deleted) OR (qty > 0))
Rows Removed by Filter: 60545
Heap Blocks: exact=667323
Buffers: shared hit=47584 read=827816 dirtied=1 written=2292
I/O Timings: read=30152.376 write=42.134
-> Bitmap Index Scan on delivery_datetime_start_datetime_end_idx (cost=0.00..864860.96 rows=32514577 width=
Index Cond: ((datetime_start >= ’2017-05-11 00:00:00’::timestamp without time zone) AND (datetime_end <
Buffers: shared hit=80 read=207997
I/O Timings: read=27315.687
• 30c из 37с ушло на чтение с диска
• Отфильтровалось относительно мало строк
dataegret.com
38. 25 I/O timings
• 30c из 37с ушло на чтение с диска
• Отфильтровалось относительно мало строк
• Происходит ли значительная фильтрация строк на более высоком
уровне ?
dataegret.com
39. 25 I/O timings
• 30c из 37с ушло на чтение с диска
• Отфильтровалось относительно мало строк
• Происходит ли значительная фильтрация строк на более высоком
уровне ?
• Если да - возможно нужно соединять таблицы каким-то другим
способом, чтобы приходилось меньше читать данных
dataegret.com
40. 26 Sort
explain analyze select distinct f1 from test_ndistinct ;
QUERY PLAN
-------------------------------------------------------------------------------------------
Unique (cost=1571431.43..1621431.49 rows=100000 width=4)
(actual time=4791.872..7551.150 rows=90020 loops=1)
-> Sort (cost=1571431.43..1596431.46 rows=10000012 width=4)
(actual time=4791.870..6893.413 rows=10000000 loops=1)
Sort Key: f1
Sort Method: external merge Disk: 101648kB
-> Seq Scan on test_ndistinct (cost=0.00..135314.12 rows=10000012 width=4)
(actual time=0.041..938.093 rows=10000000 loops=1)
Planning time: 0.099 ms
Execution time: 7714.701 ms
dataegret.com
41. 27 HashAggregate
set work_mem = ’8MB’;
SET
explain analyze select distinct f1 from test_ndistinct ;
QUERY PLAN
-------------------------------------------------------------------------------------------
HashAggregate (cost=160314.15..161314.15 rows=100000 width=4)
(actual time=2371.902..2391.415 rows=90020 loops=1)
Group Key: f1
-> Seq Scan on test_ndistinct (cost=0.00..135314.12 rows=10000012 width=4)
(actual time=0.093..871.619 rows=10000000 loops=1)
Planning time: 0.048 ms
Execution time: 2396.186 ms
dataegret.com
42. 28 Ошибки планировщика
explain analyze select account_id from account
where last_update <= ’2017-10-23’ and discarded = false limit 200;
-------------------------------------------------------------------------------------------
Limit (cost=0.08..26.15 rows=200 width=4) (actual time=0.584..18.087 rows=2 loops=1)
-> Index Scan using account_last_update_special1_key on account
(cost=0.08..18878.72 rows=144854 width=4) (actual time=0.582..18.084 rows=2 loops=1)
Index Cond: (last_update <= ’2017-10-23’::date)
dataegret.com
43. 28 Ошибки планировщика
explain analyze select account_id from account
where last_update <= ’2017-10-23’ and discarded = false limit 200;
-------------------------------------------------------------------------------------------
Limit (cost=0.08..26.15 rows=200 width=4) (actual time=0.584..18.087 rows=2 loops=1)
-> Index Scan using account_last_update_special1_key on account
(cost=0.08..18878.72 rows=144854 width=4) (actual time=0.582..18.084 rows=2 loops=1)
Index Cond: (last_update <= ’2017-10-23’::date)
• Ошибки в оценке числа строк в несколько порядков могут привести в итоге к сильно
неоптимальному плану
dataegret.com
44. 28 Ошибки планировщика
explain analyze select account_id from account
where last_update <= ’2017-10-23’ and discarded = false limit 200;
-------------------------------------------------------------------------------------------
Limit (cost=0.08..26.15 rows=200 width=4) (actual time=0.584..18.087 rows=2 loops=1)
-> Index Scan using account_last_update_special1_key on account
(cost=0.08..18878.72 rows=144854 width=4) (actual time=0.582..18.084 rows=2 loops=1)
Index Cond: (last_update <= ’2017-10-23’::date)
• Ошибки в оценке числа строк в несколько порядков могут привести в итоге к сильно
неоптимальному плану
• Можно посмотреть на собираемую autoanalyze статистику чтобы понять причину
dataegret.com
45. 28 Ошибки планировщика
explain analyze select account_id from account
where last_update <= ’2017-10-23’ and discarded = false limit 200;
-------------------------------------------------------------------------------------------
Limit (cost=0.08..26.15 rows=200 width=4) (actual time=0.584..18.087 rows=2 loops=1)
-> Index Scan using account_last_update_special1_key on account
(cost=0.08..18878.72 rows=144854 width=4) (actual time=0.582..18.084 rows=2 loops=1)
Index Cond: (last_update <= ’2017-10-23’::date)
• Ошибки в оценке числа строк в несколько порядков могут привести в итоге к сильно
неоптимальному плану
• Можно посмотреть на собираемую autoanalyze статистику чтобы понять причину
• Можно посмотреть переписать запрос каким-то иным способом, заставив планировщик
соединять таблицы нужным образом и использовать нужные индексы
dataegret.com
46. 29 Что можно делать ?
• Если запрос выполняется за разумное время, смотрим его explain
analyze
• Пытаемся найти узлы, на которые больше всего уходит времени
• Нет ли у нас где-то явно пропущенных индесов, в местах где много
строк фильтруется ?
• Нет ли проблем с bloat ? Смотрим explain (analyze, buffers)
• Нет ли проблем с дисками (track_io_timing)?
• Хватает ли work_mem ?
• Не ошибкается ли планировщик в оценке числа строк на порядки?
• Не сильно ли велико время планирования?
dataegret.com
47. 30 Что можно почитать?
• depesz: Explaining the unexplainable
• PostgreSQL Manual 14.1. Using EXPLAIN
• Bruce Momjian – Explaining the Postgres Query Optimizer
• www.slideshare.net/alexius2/
dataegret.com