ru:https://highload.today/blogs/kak-perestat-nenavidet-i-polyubit-orm/ ua:https://highload.today/uk/blogs/yak-perestati-nenaviditi-i-polyubiti-orm/
logo
Базы данных      19/09/2023

Как перестать ненавидеть и полюбить ORM

Володимир Рожков BLOG

Software Architect at Devlify

Среди многих опытных разработчиков существует мнение, что ORM – это нечто плохое. Его обвиняют в низком перформансе, ненужных абстракциях и воспитании плохого вкуса.

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

История взаимодействия с ORM

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

Впоследствии я успешно пользовался JPA/Hibernate и имел неприятность только со специфическими вещами типа bigint, который не хотел мапиться то ли из-за бага Хибера, то ли из-за особенностей MariaDB.

А после ActiveRecord я не очень представляю, как можно быть производительным без ORM. Во всех своих проектах SQL мне приходилось писать только для запросов, связанных со статистикой.

Известна моя любовь к Rails, но ActiveRecord я люблю больше всего, вот, например запрос на вытягивание очередного ежедневного сбора для @Donate1024Bot

Post.where(state: "approved")
    .where.not(amount: nil)
    .where.not(goal: nil)
    .where(posted_count: 0)
    .where(scheduled_at: Time.now.utc.to_date)
    .order(:id)
    .first

Эффективная работа с ORM

Не буду по пунктам разбивать классические аргументы против, напишу, что нужно вам, чтобы быть эффективным.

Главное — хорошо знать и понимать SQL. Когда вы уже понимаете как сделать нужный вам запрос, то не будет никаких проблем с тем чтобы конвертировать его в эффективный ORM-код. Мне кажется что часто люди жалуются на код программистов, которые начали пользоваться ORM без хороших знаний SQL и нарубили дров. Такое, конечно, никуда не годится.

Второе — разобраться, как сделать, чтобы ваш ORM-фреймворк печатал в лог все запросы, которые он генерирует и делает. То, что не видишь, не можешь померить и подебажить.

Кіноклуб "Забагато драми" від Skvot.
10 лекцій та 10 практикумів, щоб зрозуміти мистецтво кіномови.Сформуй власний смак та бібліотеку фільмів і навчись писати рецензії.
Програма кіноклубу

Все ORM умеют это делать, но, по неизвестным причинам, это не везде включено по умолчанию, например, в Spring/JPA это нужно конфигурировать отдельно. Одно из огромных преимуществ ActiveRecord — это такой лог. Например, запрос сверху покажет нам следующее:

Post Load (56.3ms)  SELECT "posts".* FROM "posts" WHERE "posts"."state" = $1 AND "posts"."amount" IS NOT NULL AND "posts"."goal" IS NOT NULL AND "posts"."posted_count" = $2 AND "posts"."scheduled_at" = $3 ORDER BY "posts"."id" ASC LIMIT $4  [["state", "approved"], ["posted_count", 0], ["scheduled_at", "2023-09-18"], ["LIMIT", 1]]

В консоли оно еще и красиво раскрашено, здесь мы можем видеть: время выполнения запроса, сам запрос и «бинды», параметры, которые у него были переданы. Этой информации более чем достаточно для того, чтобы писать эффективные запросы .

Третье — понимать, что такое  N+1 и как в вашем ORM-фреймворке этого избежать. Кажется, что N+1 – это самая распространенная проблема с ORM, на что ругаются те же опытные программисты, хотя она очень легко обнаруживается и исправляется. Просто почитайте как у вас делается  includes или  FetchMode.EAGER и больше не будете с тем хлопот.

Думаю, что 95% всех проблем с ORM сводится именно к N+1 и непониманию, как с ним справиться.

Четвертое — понимать цену создания объектов и использовать методы, позволяющие избежать этого. Например, если нам нужно взять из таблицы только одно поле,  idто вместо этого  ids = User.all.map(&:id) можно использовать  ids = User.all.pluck(:id)которое не будет создавать объекты  User, а получит только массив id. Rails любезно печатает статистику по количеству инстанцированных объектов в лог, поэтому там сразу понятно, где это уже влияет на быстродействие.

Люблю ORM, использую во всех проектах, советую делать то же самое и вам.

Практический совет

Включить логи своего ORM и посмотреть запросы, которые он генерирует. Подумать, что можно улучшить и почитать документацию или Tips&Tricks к своему фреймворку.

Этот текст из личного блога , опубликованный с разрешения автора.

Онлайн-курс "Корпоративна культура" від Laba.
Як з нуля побудувати стабільну корпоративну культуру, систему внутрішньої комунікації та бренд роботодавця, з якими ви підвищите продуктивність команди, — пояснить HR-директор Work.ua.
Детальніше про курс

If you have found a spelling error, please, notify us by selecting that text and pressing Ctrl+Enter.

Онлайн-курс "Фінансовий аналіз" від Laba.
Навчіться читати фінзвітність так, щоб ухвалювати ефективні бізнес-рішення.Досвідом поділиться експерт, що 20 років займається фінансами і їхньою автоматизацією.
Детальніше про курс

Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.

Ваша жалоба отправлена модератору

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: