2012-04-26 4 views
2

Я назвал запрос @NamedQuery(name="CustomerMarket.findByMarketId", query="SELECT DISTINCT c.marketid FROM CustomerMarket c WHERE c.marketid LIKE :mask") в моем определении CustomerMarket своего класса.Предложение TOP в @NamedQuery

Я хочу взять первый 1_000 из 350_000 результатов, так я применил setMaxResult:

Query market = session.getNamedQuery("CustomerMarket.findByMarketId"); 
market.setString("mask", getMask() + "%"); 
market.setMaxResults(1000); 
List<Object> result = market.list() 

После выполнения этого запроса я проверил server.log и нашел это

select distinct customerma0_.marketid as col_0_0_ 
from CUSTOMER_MARKET_S customerma0_ 
where customerma0_.marketid like ? 

я получил правильные данные, сначала 1_000 записей, но я хочу знать, есть ли ограничение TOP и где.

Как это обрабатывается TOP?

  1. TOP применяется в вызываемую заявление, которое используется Hibernate и это не отображается в журнале
  2. TOP применяется после получения результата от БД и фильтров данных на Java стороне
  3. Или что-нибудь еще

Я установил persistance.xml и log4j.properties для отображения почти всего, но я думаю, что нет проблем, так как у меня есть SQL-скрипт.

EDIT: Я сделал некоторые измерения производительности в обоих случаях (с и без setMaxResults) и получили следующие сроки:

long time = System.currentTimeMillis(); 
market.list(); 
LOGGER.info("time: " + (System.currentTimeMillis() - time) + "ms"); 

В первом случае без ТОП я имел 1400ms средний расход времени на Выбрать. Во втором случае, когда реализована функция TOP, у меня было среднее время на потребление около 150 мс.

Было также сказано, что эта реализация TOP может зависеть от используемого диалекта Hibernate (мы используем Sybase). И выбор, который появляется в журнале, точно такой же, который отправляется в БД. Но в этом случае нормально, что преобразование 350k результатов из набора результатов (или как результат сохраняется в сеансе Hibernate) в структуру List без каких-либо метаданных занимает такое долгое время? я могу себе представить, что внутренне он преобразуется что-то подобное:

**SQL generating process** 
**SQL setting parameters** 
ResultSet rs = executeQuery(); 
List<Object[]> result = new ArrayList<Object[]>(rs.getFetchSize()); 
int rowSize = rs.getMetaData().getColumnCount() 
while (rs.next) { 
    Object[] row = new Object[rowSize]; 
    for (int i = 0; i < rowSize; i++) { 
    row[i] = rs.getObject(i); 
    } 
} 

Это не кажется настолько сложным, так почему существует разница во времени. Наверное, я наивна, потому что Hibernate - сложная структура с множеством функций. :-D

ответ

0

Кажется, что моя проблема в БД, которую я использую для своего приложения. На ссылке www.petefreitag.com/item/59.cfm описано, как пользователь может ограничить количество результатов. Как вы можете видеть, единственная Sybase имеет такой выбор, разделенный на два отдельных действия (SET + SELECT). Поэтому вся проблема заключается в том, что первое действие не регистрируется, а второе -.

Смежные вопросы