[SQL] Ценность уместного комментария
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
У каждого из нас есть задача, над решением которой ты долго и безуспешно бьешься, которую изучил уже и вдоль и поперек, но все равно не можешь получить нужный результат. При этом одни уверены, что твоя задача в принципе не имеет решения, другие - что проблемы вообще нет. Такой задачей для меня была длительность выполнения запросов к хранилищу данных на Greenplum. И как же приятно наконец-то написать, что я эту проблему победил!
Когда пытаешься понять, почему запросы занимают столько времениИз раза в раз при работе с хранилищем на ожидание результата запроса уходило по несколько минут. Причем не важно, запрос выбирает данные из таблицы на десять строк, или на миллион - время на ожидание будет соизмеримым. А любой простой в таком творческом процессе, как аналитика - это просто пытка!Я много раз заходил на исправление такого поведения. Начал с тюнинга sql клиента. DBeaver предлагает пользователям целую кучу разных тонких настроек - кажется, я перепробовал их все, но успеха не достиг. Следом перепробовал настройки самого драйвера PostgreSQL - эффект тот же. Все это время перед глазами был пример специализированного клиента для Greenplum - Aginity Workbench, в котором из коробки скорость выполнения аналогичных запросов ощутимо выше. Эта прога была дополнительным раздражающим фактором, так как найти причины такого ускорения у меня не получалось - ее исходный код закрыт и работает она только по лицензии, а подключение к greenplum в ней происходит при помощи нативных инструментов, а не обычных jdbc драйверов.Озарение пришло, когда заглянул в системную вьюху pg_stat_activity - оказалось, что от клиента к базе в действительности летит не один запрос на данные, а два: сначала происходит выборка данных по запросу, а затем - чтение метаданных для этой выборки из pg_catalog. Причем из общего времени выполнения большую часть занимает именно чтение метаданных.
В этот момент я испытал целую бурю эмоций - от радости, что наконец-то нашел проблему, до недоумения от самой сути находки. То, что каталог прилично нагружен, я знал и раньше: к хранилищу сейчас подключено уже больше 250 систем-источников, в каждом не одна сотня таблиц, а в самих таблицах может быть двухуровневое партиционирование. Greenplum учитывает каждую партицию как отдельный объект, поэтому системные представления вроде pg_class прилично раздуваются. Но неужели действительно нужно обращаться к каталогу при любом запросе данных?К счастью, драйвер постгреса имеет открытый исходный код, поэтому можно самостоятельно посмотреть, что же происходит под капотом. Заглянул в код, нашел нужный класс PgResultSetMetaDataи его метод, который запрашивает метаданные - fetchFieldMetaData. Содержимое обнадеживает - похоже, без метаданных можно обойтись: fetchFieldMetaData вызывается из нескольких других методов, которые для моих целей не так важны, при этом сами эти методы допускают возврат пустого объекта, что намекает на возможность выпилить из кода вообще все обращения к fetchFieldMetaData, а значит избежать медленного запроса к каталогу.Подробнее про методы:
- isAutoIncrement. От запроса метаданных в этом методе легче всего отказаться: в нашем хранилище таких полей нет, да и комментарий "It is believed that PostgreSQL does not support this feature" как бы намекает, что и для других баз он не пригодится.
public boolean isAutoIncrement(int column) throws SQLException {
fetchFieldMetaData();
Field field = getField(column);
FieldMetadata metadata = field.getMetadata();
return metadata != null && metadata.autoIncrement;
}
- isNullable. При отсутствии метаданных в резалтсете все поля будут считаться nullable - не велика потеря.
public int isNullable(int column) throws SQLException {
fetchFieldMetaData();
Field field = getField(column);
FieldMetadata metadata = field.getMetadata();
return metadata == null ? ResultSetMetaData.columnNullable : metadata.nullable;
}
- getBaseColumnName. В коде драйвера этот метод используется в updatable резалтсетах при обновлении значений. В мои планы не входит использование этого функционала, но на всякий случай можно будет прикрутить выбрасывание исключений при вызове таких методов.
public String getBaseColumnName(int column) throws SQLException {
Field field = getField(column);
if (field.getTableOid() == 0) {
return "";
}
fetchFieldMetaData();
FieldMetadata metadata = field.getMetadata();
return metadata == null ? "" : metadata.columnName;
}
- getBaseSchemaName и getBaseTableName. Возвращают название схемы/таблицы, в которой находится запрошенный атрибут. В коде драйвера метод нигде не используется, мне эти сведения тоже не особо нужны.
public String getBaseSchemaName(int column) throws SQLException {
fetchFieldMetaData();
Field field = getField(column);
FieldMetadata metadata = field.getMetadata();
return metadata == null ? "" : metadata.schemaName;
}
public String getBaseTableName(int column) throws SQLException {
fetchFieldMetaData();
Field field = getField(column);
FieldMetadata metadata = field.getMetadata();
return metadata == null ? "" : metadata.tableName;
}
Проверяю влияние по коду, комментирую вызов метода fetchFieldMetaData, собираю jar файл драйвера, подсоединяюсь с его помощью к базе, иииии…Сказать, что это дало результат - это не сказать ничего. Запросы теперь просто летают. Ускорение - в разы. Отправил коллегам на тест - отзывы примерно такие:
Дополнительный бонус, который греет сердце: отказываясь от необязательных запросов метаданных к каталогу pgclass, мы снимаем с него лишнюю нагрузку. Не уверен, что для хранилища это дает какой-либо значимый эффект, но тут как в борьбе за экологию - радует даже то, что ты хоть сколько нибудь улучшаешь ситуацию.В общем, не опускайте руки, если проблема долго не сдается - вполне вероятно, что ответ где-то рядом и от успеха вас отделяет какая-то мелочь. В моем случае такой мелочью были символы комментариев, которые нужно было расставить на правильные места. P.S. В итоговой версии кода создал новый параметр подключения драйвера runtimeMetaDisable. Вызов метаданных и выбрасывание исключений привязал к его значению. Такой подход более гибок, чем жестко закомментированный вызов метода и позволяет управлять поведением драйвера в зависимости от потребностей. Код выложил на гитхаб. Если у вашей базы тяжелый каталог и вы хотите попробовать драйвер в деле, но не знакомы с миром java и не знаете, как собрать jar файл драйвера - напишите в комментариях!
===========
Источник:
habr.com
===========
Похожие новости:
- [PostgreSQL, Администрирование баз данных, Data Engineering] Логическая репликация в PostgreSQL. Репликационные идентификаторы и популярные ошибки
- [PostgreSQL] Постгрессо 29
- [MySQL, PostgreSQL, Веб-аналитика, DevOps] Подключение БД с SSH-туннелем к PowerBI
- [DevOps, Kubernetes] Argo CD: готов к труду и обороне в Kubernetes (перевод)
- [Информационная безопасность, NoSQL, Big Data, Софт] Определение объёма кластера Elasticsearch и тестирование производительности в Rally
- [Информационная безопасность, Тестирование веб-сервисов] «Осторожно, печеньки!»: советы начинающим тестировщикам в сфере безопасности
- [SQL, Хранилища данных, Веб-аналитика, Управление продуктом] Как мы в IVI используем массивы в ClickHouse для подсчета продуктовых метрик
- [Системное администрирование, MySQL, PostgreSQL, Администрирование баз данных] Углубленный мониторинг баз данных с помощью DBmarlin – вебинар
- [Python, PostgreSQL, SQL] Поговорим о RFM-анализе
- [Высокая производительность, SQL, Проектирование и рефакторинг, Microsoft SQL Server] Напильник и щепотка фантазии… или как слепить Enterprise из SQL Server Express Edition
Теги для поиска: #_sql, #_greenplum, #_postgres, #_jdbc, #_driver, #_upravlenie_dannymi_v_rostelekom (управление данными в ростелеком), #_blog_kompanii_rostelekom (
Блог компании Ростелеком
), #_sql
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:54
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
У каждого из нас есть задача, над решением которой ты долго и безуспешно бьешься, которую изучил уже и вдоль и поперек, но все равно не можешь получить нужный результат. При этом одни уверены, что твоя задача в принципе не имеет решения, другие - что проблемы вообще нет. Такой задачей для меня была длительность выполнения запросов к хранилищу данных на Greenplum. И как же приятно наконец-то написать, что я эту проблему победил! Когда пытаешься понять, почему запросы занимают столько времениИз раза в раз при работе с хранилищем на ожидание результата запроса уходило по несколько минут. Причем не важно, запрос выбирает данные из таблицы на десять строк, или на миллион - время на ожидание будет соизмеримым. А любой простой в таком творческом процессе, как аналитика - это просто пытка!Я много раз заходил на исправление такого поведения. Начал с тюнинга sql клиента. DBeaver предлагает пользователям целую кучу разных тонких настроек - кажется, я перепробовал их все, но успеха не достиг. Следом перепробовал настройки самого драйвера PostgreSQL - эффект тот же. Все это время перед глазами был пример специализированного клиента для Greenplum - Aginity Workbench, в котором из коробки скорость выполнения аналогичных запросов ощутимо выше. Эта прога была дополнительным раздражающим фактором, так как найти причины такого ускорения у меня не получалось - ее исходный код закрыт и работает она только по лицензии, а подключение к greenplum в ней происходит при помощи нативных инструментов, а не обычных jdbc драйверов.Озарение пришло, когда заглянул в системную вьюху pg_stat_activity - оказалось, что от клиента к базе в действительности летит не один запрос на данные, а два: сначала происходит выборка данных по запросу, а затем - чтение метаданных для этой выборки из pg_catalog. Причем из общего времени выполнения большую часть занимает именно чтение метаданных. В этот момент я испытал целую бурю эмоций - от радости, что наконец-то нашел проблему, до недоумения от самой сути находки. То, что каталог прилично нагружен, я знал и раньше: к хранилищу сейчас подключено уже больше 250 систем-источников, в каждом не одна сотня таблиц, а в самих таблицах может быть двухуровневое партиционирование. Greenplum учитывает каждую партицию как отдельный объект, поэтому системные представления вроде pg_class прилично раздуваются. Но неужели действительно нужно обращаться к каталогу при любом запросе данных?К счастью, драйвер постгреса имеет открытый исходный код, поэтому можно самостоятельно посмотреть, что же происходит под капотом. Заглянул в код, нашел нужный класс PgResultSetMetaDataи его метод, который запрашивает метаданные - fetchFieldMetaData. Содержимое обнадеживает - похоже, без метаданных можно обойтись: fetchFieldMetaData вызывается из нескольких других методов, которые для моих целей не так важны, при этом сами эти методы допускают возврат пустого объекта, что намекает на возможность выпилить из кода вообще все обращения к fetchFieldMetaData, а значит избежать медленного запроса к каталогу.Подробнее про методы:
Дополнительный бонус, который греет сердце: отказываясь от необязательных запросов метаданных к каталогу pgclass, мы снимаем с него лишнюю нагрузку. Не уверен, что для хранилища это дает какой-либо значимый эффект, но тут как в борьбе за экологию - радует даже то, что ты хоть сколько нибудь улучшаешь ситуацию.В общем, не опускайте руки, если проблема долго не сдается - вполне вероятно, что ответ где-то рядом и от успеха вас отделяет какая-то мелочь. В моем случае такой мелочью были символы комментариев, которые нужно было расставить на правильные места. P.S. В итоговой версии кода создал новый параметр подключения драйвера runtimeMetaDisable. Вызов метаданных и выбрасывание исключений привязал к его значению. Такой подход более гибок, чем жестко закомментированный вызов метода и позволяет управлять поведением драйвера в зависимости от потребностей. Код выложил на гитхаб. Если у вашей базы тяжелый каталог и вы хотите попробовать драйвер в деле, но не знакомы с миром java и не знаете, как собрать jar файл драйвера - напишите в комментариях! =========== Источник: habr.com =========== Похожие новости:
Блог компании Ростелеком ), #_sql |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:54
Часовой пояс: UTC + 5