Загружать страницу данных одновременно - PullRequest
6 голосов
/ 23 декабря 2010

У меня есть сетка данных со страницами с количеством строк более 10 тыс., Поэтому она очень медленная при первой загрузке. Каков наилучший способ решения этой проблемы. Я читал, что JDBC-пейджинг является обычным решением для такой проблемы, но некоторые люди говорят, что использовать SQL ROWNUM - более простое решение, поэтому я сначала хотел спросить.

Если вы считаете, что пейджинг является лучшим решением, не могли бы вы дать мне пару советов о том, как это сделать (ссылка на имплиментацию и т. Д.)

Ответы [ 8 ]

2 голосов
/ 30 декабря 2010

Это очень хороший вопрос, и нет единого хорошего ответа для каждого случая. Я использовал и видел различные стратегии, каждая из которых имеет свои плюсы и минусы.

Загрузка сразу - хорошо, это хорошо с небольшими таблицами и когда данные фильтруются. Когда пользователь переходит на другие страницы, никакие дополнительные запросы не отправляются в базу данных. Минус - высокая стоимость при начале взаимодействия и очень высокие требования к памяти. Когда типичен, пользователь не будет прокручивать все данные, это пустая трата ресурсов. Однако для небольших словарей это, вероятно, лучшее решение.

Пейджинг с использованием лимита / смещения (PostgreSQL), rownum (Oracle) или любого другого ключевого слова. Плюс - высокое время загрузки первой страницы. Минус - каждая следующая страница загружается медленнее, с более тяжелой работой на сайте базы данных. Лучшая стратегия, когда пользователь обычно видит одну или несколько первых страниц. Худшее, когда пользователь прокрутит все данные. Это работает довольно хорошо, когда набор упорядочен по первичному ключу, однако ужасно, когда набор данных фильтруется и упорядочивается не по индексу. Для каждой страницы она вызывает фильтрацию (возможно, с полным сканированием таблицы) и сортировку полного набора данных в памяти!

Прокрутка с использованием курсора базы данных. Это самая опасная стратегия. База данных открывает курсор для запроса, и когда пользователю требуется следующая страница, курсор перемещается. Оптимальная стратегия для случая, когда пользователь обычно просматривает все данные. Предпочтительная стратегия для отчетов. Однако в интерактивном режиме пользователя требуется, чтобы соединение с базой данных было заблокировано на время взаимодействия. Никто другой не может использовать это! А количество подключений к базе данных ограничено! Это также очень сложно реализовать в веб-приложении, где вы не знаете, закрыл ли пользователь браузер или все еще анализирует данные - вы не знаете, когда прервать соединение.

2 голосов
/ 26 декабря 2010

Пейджинг подходит, и тактика в первом ответе на на этот вопрос должна сработать для Oracle.

1 голос
/ 31 декабря 2010

Самый простой способ - отслеживать, на какой странице вы находитесь, а затем с помощью SQL указать смещение и лимит. На оракуле это делается indexval и rownum, но это не стандартно, и другие dbms используют лимит вместо этого.

Вы также можете работать независимо от базы данных и использовать JPA поверх JDBC. Класс Jpa Query поддерживает функции setFirstResult и setMaxResults для той же цели. Под капотом он будет выполнять соответствующие sql для вас в зависимости от используемых вами дБмс.

Выбор счетчика () помогает определить количество страниц.

1 голос
/ 26 декабря 2010

Проверьте эту ссылку о запросах на нумерацию страниц в Oracle.

http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html

На основе двух входных параметров ((1) номер страницы и (2) количество результатов, отображаемых на странице), Вы можете использовать запрос для получения нужных вам результатов.

Также проверьте запрос, на который указал Дон Роби выше. Это так же хорошо, но я хотел бы указать вам более подробную информацию о оракуле и то, как она обрабатывается.

0 голосов
/ 30 декабря 2010

Вы, вероятно, читаете запись за записью.Итак, для каждой записи есть два переключателя контекста:

  • Java -> БД Oracle (отправить запрос на запись)
  • (Oracle работает)
  • Oracle DB -> Java (вернуть запись)

Идите и проверьте свой код и посмотрите, сможете ли вы найти что-то в цикле for / while, которое вы можете улучшить.

И еще: я знаю кого-то, кто много работает с Oracle.Он сказал мне, что вы можете избежать большинства циклов, написав интеллектуальные запросы.Таким образом, написание хорошего запроса - огромное улучшение производительности.

0 голосов
/ 29 декабря 2010

для более общего решения, вы должны использовать метод Statement.setFetchSize. С помощью этого метода вы можете ограничить количество записей, извлекаемых из базы данных. По умолчанию все записи извлекаются.

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

0 голосов
/ 23 декабря 2010

Вам понадобятся два запроса.Они могут быть следующими:

  1. начальный запрос select * from tableName где rownum <= pagesize </i>
  2. постраничный запрос select * from tableName, где indexVal> index-of-last-page и rownum <= pagesize </i>

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

Эти запросы предполагают, что вы не упорядочиваете свои результаты.Если вы заказываете возвращаемое значение, тогда запросы будут варьироваться следующим образом:

  1. начальный запрос select * from (select * from tableName order by blah)где rownum <= pagesize </i>
  2. Постраничный запрос select * from (выбрать * из tableName, где indexVal> порядок индекса последней страницы по бла) rownum <= размер страницы </i>
0 голосов
/ 23 декабря 2010

Вы можете ограничить свой набор результатов в вашем sql запросе с ключевым словом limit.

Выберите * из TableName, где id> ... упорядочить по fieldName asc limit 50;

Выберите * из TableName, где id <... упорядочить по fieldName desc limit 50; </p>

Вам нужно добавить логику для перемотки назад и вперед.

одно из возможных решений - получить идентификатор элемента в вашем списке, наименьший для предыдущей страницы, наибольший для следующей страницы, и использовать аналогичные sqls, как указано выше

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...