man standing in a mysterious library, digital art style, illustration painting
Среди многих опытных разработчиков существует мнение, что 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
Не буду по пунктам разбивать классические аргументы против, напишу, что нужно вам, чтобы быть эффективным.
Главное — хорошо знать и понимать SQL. Когда вы уже понимаете как сделать нужный вам запрос, то не будет никаких проблем с тем чтобы конвертировать его в эффективный ORM-код. Мне кажется что часто люди жалуются на код программистов, которые начали пользоваться ORM без хороших знаний SQL и нарубили дров. Такое, конечно, никуда не годится.
Второе — разобраться, как сделать, чтобы ваш ORM-фреймворк печатал в лог все запросы, которые он генерирует и делает. То, что не видишь, не можешь померить и подебажить.
Все 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 к своему фреймворку.
Этот текст из личного блога , опубликованный с разрешения автора.
В благословенные офисные времена, когда не было большой войны и коронавируса, люди гораздо больше общались…
Вот две истории из собственного опыта, с тех пор, когда только начинал делать свою карьеру…
«Ты же программист». За свою жизнь я много раз слышал эту фразу. От всех. Кто…
Отличные новости! Если вы пропустили, GitHub Copilot — это уже не отдельный продукт, а набор…
Несколько месяцев назад мы с командой Promodo (агентство инвестировало в продукт более $100 000) запустили…
Пару дней назад прочитал сообщение о том, что хорошие курсы могут стать альтернативой классическому образованию.…