Понимание критериев Hibernate#setMaxResults

на docs говорят:

Criteria setMaxResults(int maxResults)
>Set a limit upon the number of objects to be retrieved.

предположим, у меня есть следующее Criteria:

Criteria criteria = createCriteria(); // creates criteria for MY_TABLE entity
criteria.list().length; // let's say there's a million records in this table

будет добавлять criteria.setMaxResults(1) вернуть только одну строку? Или он все равно вернет 1 миллион строк, но выберет одну из них?

при выполнении запроса, подобного моему приведенному выше примеру кода против моей Oracle DB, я увидел, что ... ROWNUM < 2 SQL создавался.

но, когда я посмотрел ROWNUM FAQ, Я не понял, если ROWNUM будет применяется до получение записей или после. Я ожидал бы, что "до" будет эффективным, тогда как "после" не будет для большого набора результатов.

ROWNUM вычисляется после выбора записей из базы данных и Перед выполнением сортировки.

1 ответов


будет добавлять условия.setMaxResults(1) возвращает только одну строку? Или, будет ли он по-прежнему возвращать 1 миллион строк, но выбрать один из них?

Да, он вернет только одну строку, hibernate использует функцию db для ограничения результатов. Hibernate не будет собирать 1 миллион строк, но db будет, а затем выберите первую строку(это утверждение касается запроса, сгенерированного hibernate, а не ROWNUM).

предположим, у вас есть таблица с именем user, в котором у вас есть 8 строк.

+----+-----------+-------+
| id |   name    | score |
+----+-----------+-------+
|  1 | Xyz       |   500 |
|  2 | Name3     |   200 |
|  3 | Name2     |   300 |
|  4 | Name4     |   100 |
|  5 | SomeName  |   600 |
|  6 | BSomeName |   150 |
|  7 | Asomename |    80 |
|  8 | Csomename |   700 |
+----+-----------+-------+

теперь выполните следующие критерии.

criteria.add(Restriction.le("score", 500));
criteria.addOrder(Order.asc("name"));
criteria.setMaxResults(2);

следующий запрос, сгенерированный Hibernate.

select * from(select * from user where score <= 500 order by name) where ROWNUM < 3; 

DB выполнит его в следующем порядке.

  • найти все строки, где оценка меньше или равна 500. здесь он найдет 6 рядов.
  • упорядочить все строки по имени в порядке возрастания.
  • присвоить ROWNUM в каждой строке.
  • найти все строки с ROWNUM менее 3 и вернуть их.

результат будет.

+----+-----------+-------+
| id |   name    | score |
+----+-----------+-------+
|  7 | ASomeName |   80  |
|  6 | Bsomename |   150 |
+----+-----------+-------+

DB будет выполнять вышеуказанные шаги независимо от того, сколько записей, поэтому, когда у вас есть порядок и есть много строк, которые удовлетворяют условию, запрос будет очень медленным.

я не понял, будет ли применен ROWNUM перед извлечением записи, или после. Я ожидал бы, что "до" будет эффективным, тогда как "после" не было бы для большого результирующий набор.

ROWNUMS индексируются строки, которые удовлетворяют всем заданным условиям. DB будет продолжать проверять каждую строку применять все условия, указанные в предложении WHERE, если everythig в порядке, то назначьте номер этой строке, перейдите к следующему. Как говорит доктор ROWNUM is evaluated AFTER records are selected from the database значит все условия выполнены.

перед исполнением приказа по пункту.

ROWNUM отличается от предела в другом базами данных(MySQL, Postgrage и т. д.). Я. E LIMIT находит все строки, сортирует их и возвращает ограниченные результаты. в то время как ROWNUM будет назначен строкам, как только он удовлетворяет всем условиям. Вот почему hibernate сгенерировал внутренний запрос для получения согласованных отсортированных результатов.

If с теми же данными, что и в приведенной выше таблице, если вы выполните следующий запрос.

select * from user where score <= 500 where row_num < 3 order by name;

вы получите следующий результат.

+----+-----------+-------+
| id |   name    | score |
+----+-----------+-------+
|  3 | Name2     |   300 |
|  2 | Name3     |   200 |
+----+-----------+-------+

это потому, что DB начинает находить строки, удовлетворяющие условию (оценка

читать этой и этой статьи они действительно подробные.