Большие списки отображаемых тегов в режиме гибернации
-
20-09-2019 - |
Вопрос
Я использую displaytag для создания таблиц с данными из моей базы данных.Это хорошо работает, если запрошенный список не такой большой, но если размер списка превышает 2500 записей, получение списка результатов занимает очень много времени (более 5 минут).Мне было интересно, является ли такое поведение нормальным.
Как вы обрабатываете большой список / запросы, которые возвращают большие результаты?
Решение
Эта статья ссылки на пример приложения о том, как приступить к решению проблемы.Displaytag ожидает, что ему будет передан полный набор данных для создания ссылок подкачки и обработки сортировки.Это своего рода разрушает идею внешней подкачки данных и извлечения только тех строк, которые запрашиваются (в качестве пользовательских страниц к ним).Проект, на который дана ссылка в статье, описывает, как приступить к настройке такого рода устройств.
Если вы работаете с большой базой данных, у вас также может возникнуть проблема с выполнением вашего запроса.Я предполагаю, что вы исключили это.Если нет, у вас есть SQL, как упоминалось ранее - я бы прогнал его через анализатор запросов DB2, чтобы посмотреть, есть ли какие-либо узкие места в базе данных.Следующий шаг по цепочке - запустить тест вызова Hibernate / DAO в модульном тестировании без displaytag в миксе.Опять же, судя по тому, как вы это сформулировали, звучит так, будто вы уже делали это.
Другие советы
Displaytag извлекает и сохраняет все в памяти (сеанс).Hibernate также делает это.Вы не хотите, чтобы все содержимое таблицы БД находилось сразу в памяти (однако, если замедление уже начинается с 2500 строк, это больше похоже на плохо оптимизированный SQL-запрос / таблицу БД;2500 строк должны быть орешками для приличной базы данных, но ладно, это уже другая история).
Скорее создайте HTML-таблицу самостоятельно с небольшой помощью JSTL c:forEach
и рюмку EL.Сохраняйте один или два параметра запроса в фоновом режиме в input type="hidden"
:первая строка, которая будет отображена (firstrow
) и, в конечном счете, количество строк, которые будут отображаться одновременно (rowcount
).
Затем в вашем классе DAO просто выполните SELECT stuff FROM data LIMIT firstrow OFFSET rowcount
или что-то в этом роде, в зависимости от используемой базы данных.В MySQL и PostgreSQL вы можете использовать LIMIT
и/или OFFSET
пункт вроде этого.В Oracle вам нужно будет запустить подзапрос.В MSSQL и DB2 вам нужно будет создать SP.Вы можете сделать это с помощью HQL.
Затем, чтобы пролистать таблицу, просто используйте кучу кнопок, которые инструктируют серверный код вводить / уменьшать firstrow
с rowcount
каждый раз.Просто посчитай.
Редактировать:вы прокомментировали, что используете DB2.Я провел небольшое исследование, и оказалось, что вы можете использовать функцию UDB OLAP ROW_NUMBER()
для этого:
SELECT id, colA, colB, colC
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY id) AS row, id, colA, colB, colC
FROM
data
) AS temp_data
WHERE
row BETWEEN 1 AND 10;
Этот пример должен возвращать первые 10 строк из data
таблица.Вы можете параметризовать этот запрос, чтобы использовать его повторно для каждой страницы.Это более эффективно, чем запрашивать всю таблицу в памяти Java.Также убедитесь, что таблица правильно проиндексирована.