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 до свого фреймворку.
Цей текст з особистого блогу, опублікований з дозволу автора.
Блогер та розробник Джозеф Круз розповів, чому не варто писати ідеальний код та чому це…
Днями я завзято нила про щось ChatGPT (експериментую між сеансами з живим терапевтом). І от…
«Крутіть колесо, щоб отримати знижку до 50%!» «Натисніть тут, щоб відкрити таємничу пропозицію!» «Зареєструйтесь зараз,…
Дуже хочеться робити якісь десктопні апки. Сумую за часами коли всі програми були offline-first, і…
Надсилаючи криптовалюту, багато новачків ставлять запитання: як працюють комісії та чому вони відрізняються в різних…
Нова афера набирає обертів — ось детальний розбір того, як фальшиві потенційні роботодавці намагаються вкрасти…