2015-09-22 3 views
2

Я хочу, чтобы выбрать 10 лучших записей, можно использовать один из:JDBC: LIMIT против setmaxrows (Resultset)

  • Использование setmaxrows в Resultset
  • Использование LIMIT и OFFSET в SQL Statement

Мой вопрос: каковы преимущества и недостатки между ними?

ответ

2

Преимущество setmaxrows является то, что вы можете создавать универсальные операторы, действующие в Postgres, Oracle, MySQL и т.д. В Oracle Пользуется RowNum синтаксис, Postgres - предел, msqsql - топ

По скорости он не кажется, что нет разница.

+1

... если драйвер JDBC достаточно умный –

+0

У вас есть информация о некоторых драйверах, которые не являются умными в 2015 году? –

+0

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

4

В большинстве случаев вы хотите использовать предложение LIMIT, но в конце дня оба достигнут того, чего вы хотите. Этот ответ ориентирован на JDBC и PostgreSQL, но применим к другим языкам и базам данных, которые используют подобную модель.

документация JDBC для Statement.setMaxRows говорит

Если лимит превышен, то лишние строки отброшены.

Т.е. сервер базы данных может возвращать больше строк, но клиент просто игнорирует их. Ограничение драйвера PostgreSQL JDBC ограничено как на стороне клиента, так и на стороне сервера. Для клиентской стороны взгляните на использование maxRows in the AbstractJdbc2ResultSet. Для серверной стороны взгляните на maxRows in QueryExecutorImpl.

на стороне сервера, то PostgreSQL LIMIT documentation говорит:

Оптимизатор принимает LIMIT во внимание при создании запроса, плана

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

+2

Я думаю, вы ошибаетесь: «кажется, ограничивает только клиентскую сторону». Вы можете посмотреть метод org.postgresql.core.v3.QueryExecutorImpl # sendOneQuery'. – sibnick

+0

Я действительно верю, что ты прав @ сибник. Я обновлю ответ. Не смотря на исходный код сервера, я полагаю, что _possible_ сервер может игнорировать информацию, но это кажется маловероятным (и плохой ход). –

+0

В некоторых случаях он должен вычислить весь набор результатов, прежде чем он сможет вернуть только некоторые из них, но он пытается выбрать план, чтобы избежать этого. В этих случаях это то же самое, если вы используете LIMIT. –

2

setFetchSize Дает драйвер JDBC подсказку о количестве строк, которые должны быть извлечены из базы данных, когда для объектов ResultSet, сгенерированных этим оператором, требуется больше строк.

setMaxRows Устанавливает ограничение для максимального количества строк, которое любой объект ResultSet, сгенерированный этим объектом Statement, может содержать заданное число.

Думаю, используя выше 2 API JDBC, вы можете попробовать с помощью setFetchSize вы можете попробовать, если он работает для 100K записей. Кроме того, вы можете выбрать пакет и сформировать ArrayList и вернуть его в отчет Jasper.

1

не уверен, что я прав, но я помню, в прошлом я был вовлечен в большой проект, чтобы изменить все запросы, которые, как ожидается, вернут одну строку в «TOP 1» или numrows = 1. Причина заключалась в том, что БД прекратила поиск «следующих возможных совпадений», когда был использован этот «намек». И в условиях большого объема это действительно имело значение. Замечание о том, что вы можете «игнорировать» лишние записи в клиенте или в наборе результатов, недостаточно. Вы должны избегать ненужных чтений как можно раньше.Но я понятия не имею, добавляют ли методы JDBC эти специальные привязки к запросу y/n. Мне, возможно, придется протестировать, однако, чтобы увидеть и использовать его ... я не специалист по db и могу представить, что я не прав, но «Speedwise кажется неважным» может быть неправильным предположением ... Например. если вас попросят найти в поле для красных шаров, и вам нужен только один, он не добавит значения, чтобы продолжать поиск всех, где вам достаточно. Тогда важно указать «TOP 1» ...