Как стать автором
Обновить

Комментарии 15

Интересно, насколько быстрее станет работа с базой данных, если ORM при компиляции программы будет компилировать запросы в БД уже в готовом байт-коде?

А разве код не зависит от статистики?

От статистики зависит в связи с бедностью SQL - невозможно объяснить СУБД, как лучше выполнить запрос исходя из знания, какие данные хранятся в таблицах.

Выигрыш будет сильно меньше, чем хотелось бы:

  • Основное время БД находится в ожидании IO

  • Даже замена всех SQL запросов захардкоженными параметрами на параметризуемые даёт крайне низкий профит по производительности (другое дело, что эта срань отравляет кэш запросов, но о нём далее)

  • Наконец, БД кэширует как разобранные запросы, так и позволяет работать с prepared statements -- теми самыми скомпилированными запросами

Что реально даёт профит:

  • Внимательный разбор плана каждого мало-мальски сложного запроса

  • В случае ORM внимательный анализ запросов, которые она генерит

  • Наконец, ORM не позволяет забить на изучение SQL и RDBMs

А ещё декларативность SQL -- миф. В случае подзапросов БД выполнит их императивно -- начиная с самого глубоко вложенного и наверх

Кстати об оптимизаторе запросов. Воображение рисует, каким будет реально работающий оптимизатор запросов. Это должен быть робот, который находит программистов, пишущих плохой код, и нещадно их 3.1415926

Если вы можете написать робота (алгоритм), который может отличить хороший код от плохого в автоматическом режиме, то это будет большое достижение, вне зависимости от гопнических замашек.

hint: вы не можете предсказать что делает программа имея на руках программу и её данные. Halting problem, всё такое.

Я не вижу задачу невыполнимой ни в каком виде

Я не понимаю почему вы не видите задачу невыполнимой ни в каком виде.

НЛО прилетело и опубликовало эту надпись здесь

А ещё декларативность SQL -- миф. В случае подзапросов БД выполнит их императивно -- начиная с самого глубоко вложенного и наверх

Не аксиома. Запрос с подзапросом запросто может быть развёрнут анализатором в обычный JOIN (т.е. будет построен план исполнения, полностью совпадающий с планом выполнения логического аналога этого запроса, использующего JOIN).

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

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

Именно. Сложный запрос можно составить десятками разных способов, из которых два-три могут конкурировать по производительности, а все остальные являются или саботажем, или бездарностью. В своё время я насмотрелся на бездарность

Не аксиома. Запрос с подзапросом запросто может быть развёрнут анализатором

Редко, но оптимизаторы меня действительно удивляют. Иногда приятно, чаще нет. Как по мне, чем предсказуемее оптимизатор, тем ниже вероятность сюрприза на проде. Одно приятное удивление было в примере бездарного кода:

WHERE TRUNC(event_log.event_time, "YYYY.MM") = :event_day

Так вот, вместо честного TABLE FULL ACCESS оптимизатор смог использовать INDEX RANGE SCAN, разве что выгреб годовой интервал вместо суток

не думаю, что выигрыш будет существенен.


постгресовский explain analyze, например, пишет время работы планировщика и время исполнения запроса, разница обычно на порядки.
плюс для сложных запросов постгре включает генетический алгоритм, который позволяет найти «достаточно хороший» план за разумное время.


а ms sql агрессивно кэширует планы исполнения запросов (одно время периодический запуск dbcc freeproccache был описан чуть ли не в каждом втором руководстве по тюнингу связки 1c/ms sql).

Прикольно. Байт-код, похоже, фиксированного размера, чтобы проще было для переходов находить инструкцию по индексу. Виртуальная машина регистровая, и приходится указывать регистр-получатель результата. Я так понял, что идентификатор курсора - это r[0], используется, когда нужно значения колонки прочитать. Столбцы идентифицируются индексами, значит компилятор зачитывает схему таблицы для кодогенерации. Оптимизация так себе: столбец "favorite_color" зачитывается из курсора дважды, второй раз только для того, чтобы ResultsRow мог сформировать результат из последовательного набора регистров. Интересно, почему не скопировать регистр-регистр в этом случае.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории