Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Python: SQL, ORM, database, query optimization, raw queries

Когда стоит использовать нативные SQL-запросы вместо ORM?

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

Короткий ответ

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

Длинный ответ

Object-Relational Mapping (ORM) — это мощный инструмент, который абстрагирует работу с базой данных, позволяя разработчикам использовать объекты своего языка программирования вместо написания SQL. Это повышает скорость разработки, безопасность (защита от инъекций) и переносимость кода между разными СУБД. Однако эта абстракция имеет свою цену и иногда становится узким местом.

Когда ORM становится недостаточным

Есть несколько ключевых сценариев, где нативный SQL выигрывает:

  • Сложные отчеты и аналитика: Запросы, включающие множество JOIN, подзапросы, оконные функции (ROW_NUMBER, LAG), рекурсивные обходы (CTE) или группировки с фильтрацией по агрегатным функциям (HAVING). ORM может либо не поддерживать такие конструкции, либо генерировать крайне неоптимальный SQL-код.
  • Критическая производительность: Для высоконагруженных операций, где каждый миллисекунд на счету. Написав запрос вручную, можно точно контролировать его выполнение, использовать специфичные для базы индексы и оптимизации, которые ORM может проигнорировать.
  • Использование специфичных функций СУБД: Например, геопространственные функции в PostGIS, полнотекстовый поиск или специальные типы данных. ORM, ориентированный на кроссплатформенность, часто их не поддерживает.
  • Массовые операции (Bulk Operations): Обновление или вставка сотен тысяч строк. ORM обычно делает это по одной строке или небольшими пакетами, создавая огромные накладные расходы, в то время как нативный SQL-запрос с INSERT ... VALUES (...), (...), ... или UPDATE ... FROM ... выполнит задачу на порядки быстрее.

Практический пример

Рассмотрим задачу: получить для каждого отдела (department) сотрудника с максимальной зарплатой. На Django ORM это может привести к запутанному и неэффективному коду. Нативный SQL с оконной функцией будет чище и быстрее:

-- Пример для PostgreSQL
SELECT department_id, employee_id, name, salary
FROM (
    SELECT 
        department_id,
        employee_id,
        name,
        salary,
        ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) as rn
    FROM employees
) ranked
WHERE rn = 1;

В коде приложения (например, на Python с SQLAlchemy) такой запрос можно выполнить безопасно, используя текстовый SQL и передачу параметров:

from sqlalchemy import text

query = text("""
    SELECT department_id, employee_id, name, salary
    FROM (
        SELECT department_id, employee_id, name, salary,
               ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) as rn
        FROM employees
    ) ranked
    WHERE rn = 1 AND department_id = :dept_id;
""")

result = session.execute(query, {'dept_id': 5}).fetchall()
for row in result:
    print(row.name, row.salary)

Вывод: Используйте нативные SQL-запросы для сложных аналитических отчетов, операций, критичных к производительности, и для доступа к уникальным возможностям вашей СУБД. Для типичных CRUD-операций, где важна скорость разработки и безопасность, ORM остается отличным выбором. Идеальный подход — их комбинация, где ORM используется для основной работы, а нативный SQL — для решения специфичных, узких задач.

Уровень

  • Рейтинг:

    4

  • Сложность:

    6

Навыки

  • Python

    Python

  • SQL

Ключевые слова

#SQL

#ORM

#database

#query optimization

#raw queries

Подпишись на Java Developer в телеграм