Как отслеживать размер набора результатов с помощью спящего режима?

Я пытаюсь обнаружить и оптимизировать неэффективные объединения в приложении Java/Hibernate. Я заметил, что в некоторых случаях из-за характера взаимодействия узлов в наборах результатов поток данных, передаваемых по проводу, очень неэффективен.

Позвольте мне привести пример. Предположим, у вас есть запрос HQL, который выглядит так:

select s from Store s
left join fetch s.items i
left join fetch s.employees e
left join fetch s.customers c
where s.id = :id

(Игнорируйте на мгновение, что это не интеллектуальный запрос - это просто упрощенный пример).

Если вы представляете, что в данном магазине есть 1000 товаров и 10 сотрудников и 100 клиентов, вы вернете дерево объектов Java с 1111 объектами. Это может усугубить вас мыслью, что из базы данных было возвращено приблизительно 1111 строк, тогда как на самом деле в наборе результатов было 1000 000 строк!

Наличие всех столбцов делает это хуже. Если вы представляете, что каждая таблица имеет 5 столбцов, вы можете себе представить, что вы получили примерно 5555 "элементов" назад, тогда как количество ячеек (столбец строк *) в наборе результатов было фактически 20 000 000.

Очевидно, что ответственность разработчиков приложений должна быть осведомлена об этой проблеме и не писать запросы таким образом. Однако это иногда случается непреднамеренно (и менее строгими способами), и было бы здорово иметь возможность заставить приложение как-то идентифицировать эти ситуации.

Однако мне не удалось найти способ вычислить (из приложения Java/Hibernate) либо количество строк, либо количество столбцов в исходном наборе результатов. Кажется, что ни перехватчики Hibernate, ни Hibernate, ни статистика Hibernate не дают доступа к этой информации.

Любые предложения? Спасибо заранее.

Ответ 1

Есть проект под названием log4jdbc, который предоставляет прокси-драйвер JDBC, он может записывать SQL (с добавленными аргументами), а также время статистика, события открытия и закрытия соединения, даже вызовы ResultSet. Есть несколько вилок, по крайней мере один (называемый log4jdbc-remix) записывает в виде таблиц результаты.

Я бы подумал, что использование логатора jdbc.sqltiming должно быть достаточным, чтобы указать, где проблемы, тогда вы можете перейти к другим параметрам, если вам нужно. Но это звучит так, что можно взломать его, чтобы получить подсчет результатов.

Ответ 2

Hibernate - очень сложная структура. Как вы видите, он потребляет много общего времени выполнения по сравнению с сырым JDBC. И ваш запрос не обязательно будет создавать 1111 объектов, потому что Hibernate использует кеширование, кеш второго уровня и другие темные технологии для прокси-объектов и сохраняет память в зависимости от конфигурации, конечно.

Однако, если вы ищете какой-либо способ рассчитать некоторые статистические данные из вашего Java-кода, вы должны использовать Hibernate Statistics, они очень полезны в некоторых случаях, уверен, что они не работали для вас?

QueryStatistics queryStats = stats.getQueryStatistics("from Store s");
queryStats.getCacheHitCount();
queryStats.getCacheMissCount();
queryStats.getCachePutCount();
queryStats.getExecutionCount();
queryStats.getExecutionAvgTime();
queryStats.getExecutionMaxTime();
queryStats.getExecutionMinTime();
queryStats.getExecutionRowCount();

SecondLevelCacheStatistics cacheStats = stats.getSecondLevelCacheStatistics("Sale.cache");
cacheStats.getElementCountInMemory();
cacheStats.getElementCountOnDisk();
cacheStats.getEntries();
cacheStats.getHitCount();
cacheStats.getMissCount();
cacheStats.getPutCount();
cacheStats.getSizeInMemory();

CollectionStatistics collectionStats = stats.getCollectionStatistics("Sale.items");
collectionStats.getFetchCount();
collectionStats.getLoadCount();
collectionStats.getRecreateCount();
collectionStats.getRemoveCount();
collectionStats.getUpdateCount();

И есть еще больше возможностей для изучения http://www.javalobby.org/java/forums/t19807.html

Ответ 3

количество строк? "select count..." (это не похоже на выполнение его дважды. counts execute выполняется намного быстрее) количество столбцов? Отражение. скрипта с Class.getDeclaredMethods();