Нет необходимости генерировать третий запрос. Если вы пишете SQL-запросы вручную, вы можете загрузить все продажи для всех извлеченных сотрудников в виде одного запроса. Но «N + 1 запрос» возникает антишаблон когда программный код выглядит как в статье:
for (Employees e: emp) {
// process Employee
for (Sales s: e.getSales()) {
// process sale for Employee
}
}
в этом коде e.getSales()
метод загружает данные для одного сотрудника. Этот метод не располагает достаточной информацией для загрузки данных о продажах для всех других сотрудников, поскольку ORM не имеет полного списка сотрудников, для которых необходимо загрузить данные о продажах. Таким образом, ORM вынуждена загружать данные продаж каждого сотрудника в отдельный запрос.
Некоторые ORM могут автоматически устранить проблему «N + 1 запрос». Например, в PonyORM (написанный на Python) код из статьи будет выглядеть следующим образом:
# the first query loads all necessary employees
employees = select(e for e in Employee if e.lastName.startswith('WIN'))
for e in employees:
# process Employee
for sale in e.sales:
# process sale for Employee
Когда программа начинает цикл по запросу работника, PonyORM загружает все необходимые сотрудники сразу. Когда запрашиваются элементы продаж для первого сотрудника, PonyORM загружает его только для этого сотрудника (поскольку ORM не знает нашего намерения и предполагает, что, возможно, нам нужны данные о продажах только для первого сотрудника). Но когда запрашиваются данные о продажах второго сотрудника, PonyORM замечает анти-шаблон «N + 1 запрос», видит, что у нас есть N объектов сотрудников, загруженных в память, и загружает продажи для всех остальных сотрудников в одном запросе. Такое поведение можно рассматривать как эвристику. Он может загружать некоторые дополнительные объекты продаж, если наш for
-loop содержит операцию break
. Но обычно эта эвристика приводит к повышению производительности, поскольку она может значительно сократить количество запросов. Как правило, не проблема загружать некоторые дополнительные данные, гораздо важнее уменьшить количество обращений к серверу.
Вы попробовали 'Hibernate JPA 3.6.0' самостоятельно для создания запросов? Похоже, опечатка для копирования/вставки doble. –