Использование адаптивной буферизацииUsing adaptive buffering

СкачатьСкачать драйвер JDBCDownloadDownload JDBC Driver

Адаптивная буферизация, разработана для получения любых данных большого объема без затрат на использование серверных курсоров.Adaptive buffering is designed to retrieve any kind of large-value data without the overhead of server cursors. Приложения могут использовать функцию адаптивной буферизации со всеми версиями SQL ServerSQL Server, поддерживаемыми драйвером.Applications can use the adaptive buffering feature with all versions of SQL ServerSQL Server that are supported by the driver.

Как правило, когда драйвер Microsoft JDBC Driver для SQL ServerMicrosoft JDBC Driver for SQL Server выполняет запрос, он получает все результаты с сервера и загружает их в память приложения.Normally, when the Microsoft JDBC Driver для SQL ServerMicrosoft JDBC Driver for SQL Server executes a query, the driver retrieves all of the results from the server into application memory. Хотя при таком подходе минимизируется потребление ресурсов SQL ServerSQL Server, в приложении JDBC может возникнуть ошибка OutOfMemoryError для запросов, возвращающих слишком большие результаты.Although this approach minimizes resource consumption on the SQL ServerSQL Server, it can throw an OutOfMemoryError in the JDBC application for the queries that produce very large results.

Чтобы приложения могли обрабатывать результаты очень большого объема, драйвер Microsoft JDBC Driver для SQL ServerMicrosoft JDBC Driver for SQL Server реализует адаптивную буферизацию.In order to allow applications to handle very large results, the Microsoft JDBC Driver для SQL ServerMicrosoft JDBC Driver for SQL Server provides adaptive buffering. При адаптивной буферизации драйвер извлекает результаты выполнения инструкции из экземпляра SQL ServerSQL Server по мере того, как они нужны приложению, а не все сразу.With adaptive buffering, the driver retrieves statement execution results from the SQL ServerSQL Server as the application needs them, rather than all at once. Драйвер также удаляет результаты, когда приложение теряет к ним доступ.The driver also discards the results as soon as the application can no longer access them. Ниже приводятся примеры ситуаций, когда адаптивная буферизация может быть полезной.The following are some examples where the adaptive buffering can be useful:

  • Запрос возвращает результирующий набор очень большого объема. Приложение может выполнить инструкцию SELECT, возвращающую больше строк, чем может уместиться в памяти приложения.The query produces a very large result set: The application can execute a SELECT statement that produces more rows than the application can store in memory. В предыдущих версиях приложение должно было использовать серверный курсор, чтобы избежать ошибки OutOfMemoryError.In previous releases, the application had to use a server cursor to avoid an OutOfMemoryError. Адаптивная буферизация обеспечивает возможность однопроходного просмотра данных в режиме только для чтения для результирующего набора произвольно большого объема без использования курсора сервера.Adaptive buffering provides the ability to do a forward-only read-only pass of an arbitrarily large result set without requiring a server cursor.

  • Запрос создает очень большие столбцы SQLServerResultSet или значения параметра OUT класса SQLServerCallableStatement : Приложение может извлечь одно значение (столбец или параметр OUT) слишком большого объема, чтобы поместиться полностью в памяти приложения.The query produces very large SQLServerResultSet columns or SQLServerCallableStatement OUT parameter values: The application can retrieve a single value (column or OUT parameter) that is too large to fit entirely in application memory. Адаптивная буферизация позволяет клиентскому приложению извлекать такое значение в качестве потока, используя метод getAsciiStream, getBinaryStream или getCharacterStream.Adaptive buffering allows the client application to retrieve such a value as a stream, by using the getAsciiStream, the getBinaryStream, or the getCharacterStream methods. Приложение извлекает значение из экземпляра SQL ServerSQL Server по мере чтения потока.The application retrieves the value from the SQL ServerSQL Server as it reads from the stream.

Примечание

Благодаря адаптивной буферизации драйвер JDBC помещает в буфер только необходимое количество данных.With adaptive buffering, the JDBC driver buffers only the amount of data that it has to. Драйвер не позволяет любому открытому методу контролировать или ограничивать размер буфера.The driver does not provide any public method to control or limit the size of the buffer.

Настройка адаптивной буферизацииSetting adaptive buffering

Начиная с драйвера JDBC версии 2.0 по умолчанию используется значение adaptive.Starting with the JDBC driver version 2.0, the default behavior of the driver is "adaptive". Другими словами, чтобы получить адаптивное поведение буферизации, приложению не нужно запрашивать адаптивное поведение явным образом.In other words, in order to get the adaptive buffering behavior, your application does not have to request the adaptive behavior explicitly. Но в версии 1.2 по умолчанию использовался режим полной буферизации, поэтому приложение должно было запросить режим адаптивной буферизации явным образом.In the version 1.2 release, however, the buffering mode was "full" by default and the application had to request the adaptive buffering mode explicitly.

Существуют три способа, с помощью которых приложение может запросить выполнение адаптивной буферизации.There are three ways that an application can request that statement execution should use adaptive buffering:

  • Приложение может задать свойству подключения responseBuffering значение "adaptive".The application can set the connection property responseBuffering to "adaptive". Дополнительные сведения о настройке свойств подключения см. здесь.For more information on setting the connection properties, see Setting the connection properties.

  • Приложение может использовать метод setResponseBuffering объекта SQLServerDataSource для установки режима буферизации ответов для всех подключений, созданных посредством объекта SQLServerDataSource.The application can use the setResponseBuffering method of the SQLServerDataSource object to set the response buffering mode for all connections created through that SQLServerDataSource object.

  • Приложение может использовать метод setResponseBuffering класса SQLServerStatement, чтобы установить режим буферизации ответов для определенного объекта инструкции.The application can use the setResponseBuffering method of the SQLServerStatement class to set the response buffering mode for a particular statement object.

При использовании драйвера JDBC версии 1.2 приложения должны были приводить объект инструкции к классу SQLServerStatement, чтобы использовать метод setResponseBuffering.When using the JDBC Driver version 1.2, applications needed to cast the statement object to a SQLServerStatement class to use the setResponseBuffering method. Примеры кода в статьях Reading large data sample (Пример считывания большого объема данных) и Reading large data with stored procedures sample (Пример считывания большого объема данных с помощью хранимых процедур) демонстрируют это старое использование.The code examples in the Reading large data sample and Reading large data with stored procedures sample demonstrate this old usage.

Однако начиная с драйвера JDBC версии 2.0 приложения могут использовать методы isWrapperFor и unwrap для получения доступа к функциям, предоставляемым поставщиками, без необходимости реализации иерархии класса.However, with the JDBC driver version 2.0, applications can use the isWrapperFor method and the unwrap method to access the vendor-specific functionality without any assumption about the implementation class hierarchy. Пример кода можно найти в статье Updating Large Data Sample (Пример обновления большого объема данных).For example code, see the Updating large data sample topic.

Извлечение большого объема данных с помощью адаптивной буферизацииRetrieving large data with adaptive buffering

Когда большие значения считываются в первый раз с помощью методов get<Type>Stream и выполняется доступ к столбцам ResultSet и параметрам OUT CallableStatement в порядке возвращения из SQL ServerSQL Server, адаптивная буферизация минимизирует использование памяти приложения при обработке результатов.When large values are read once by using the get<Type>Stream methods, and the ResultSet columns and the CallableStatement OUT parameters are accessed in the order returned by the SQL ServerSQL Server, adaptive buffering minimizes the application memory usage when processing the results. При использовании адаптивной буферизации происходит следующее.When using adaptive buffering:

  • Методы get<Type>Stream, определенные в классах SQLServerResultSet и SQLServerCallableStatement, возвращают потоки только для чтения по умолчанию, хотя потоки можно сбросить, если они выделены приложением.The get<Type>Stream methods defined in the SQLServerResultSet and SQLServerCallableStatement classes return read-once streams by default, although the streams can be reset if marked by the application. Если приложению необходимо выполнить операцию reset для сброса потока, оно сначала должно вызвать метод mark для этого потока.If the application wants to reset the stream, it has to call the mark method on that stream first.

  • Методы get<Type>Stream, определенные в классах SQLServerClob и SQLServerBlob, возвращают потоки, которые всегда можно переместить в начальное положение потока без вызова метода mark.The get<Type>Stream methods defined in the SQLServerClob and SQLServerBlob classes return streams that can always be repositioned to the start position of the stream without calling the mark method.

Когда приложение использует адаптивную буферизацию, значения, извлекаемые методами get<Type>Stream, могут быть извлечены только один раз.When the application uses adaptive buffering, the values retrieved by the get<Type>Stream methods can only be retrieved once. Если выполняется попытка вызвать какой-либо метод get<Type> для того же столбца или параметра после вызова метода get<Type>Stream того же объекта, возникает исключение с сообщением: "Доступ к данным уже был осуществлен, данные недоступны для этого столбца или параметра".If you try to call any get<Type> method on the same column or parameter after calling the get<Type>Stream method of the same object, an exception is thrown with the message, "The data has been accessed and is not available for this column or parameter".

Примечание

Вызов ResultSet.close() в середине обработки ResultSet потребует от Microsoft JDBC Driver для SQL Server считывания и отмены всех оставшихся пакетов.A call to ResultSet.close() in the middle of processing a ResultSet would require the Microsoft JDBC Driver for SQL Server to read and discard all remaining packets. Это может занять значительное время, если запрос возвращает большой набор данных, особенно в случае, если сетевое подключение слишком медленное.This may take substantial time if the query returned a large data set and especially if the network connection is slow.

Руководство по использованию адаптивной буферизацииGuidelines for using adaptive buffering

Разработчики должны следовать данному руководству для минимизации использования памяти приложением.Developers should follow these important guidelines to minimize memory usage by the application:

  • Старайтесь не использовать свойство строки подключения selectMethod=cursor, позволяющее приложению обрабатывать результирующий набор очень большого объема.Avoid using the connection string property selectMethod=cursor to allow the application to process a very large result set. Функция адаптивной буферизации позволяет приложениям обрабатывать очень большие однопроходные результирующие наборы, доступные только для чтения, без использования серверного курсора.The adaptive buffering feature allows applications to process very large forward-only, read-only result sets without using a server cursor. Обратите внимание, что задание параметра selectMethod=cursor оказывает влияние на все однопроходные результирующие наборы только для чтения, формируемые этим подключением.Note that when you set selectMethod=cursor, all forward-only, read-only result sets produced by that connection are impacted. Другими словами, если приложение рутинно обрабатывает короткие результирующие наборы с несколькими строками, создание, считывание и закрытие серверного курсора для каждого результирующего набора будет использовать больше ресурсов как на стороне клиента, так и на стороне сервера, чем в случае, когда параметру selectMethod не присвоено значение cursor.In other words, if your application routinely processes short result sets with a few rows, creating, reading, and closing a server cursor for each result set will use more resources on both client-side and server-side than is the case where the selectMethod is not set to cursor.

  • Выполняйте считывание больших текстовых или двоичных значений в виде потоков с помощью методов getAsciiStream, getBinaryStream или getCharacterStream вместо методов getBlob или getClob.Read large text or binary values as streams by using the getAsciiStream, the getBinaryStream, or the getCharacterStream methods instead of the getBlob or the getClob methods. Начиная с версии 1.2 класс SQLServerCallableStatement предоставляет новые методы get<Type>Stream для этой цели.Starting with the version 1.2 release, the SQLServerCallableStatement class provides new get<Type>Stream methods for this purpose.

  • Убедитесь в том, что столбцы со значениями потенциально большого объема размещаются последними в списке столбцов в инструкции SELECT и что методы get<Type>Stream класса SQLServerResultSet используются для доступа к столбцам в порядке их выбора.Ensure that columns with potentially large values are placed last in the list of columns in a SELECT statement and that the get<Type>Stream methods of the SQLServerResultSet are used to access the columns in the order they are selected.

  • Убедитесь в том, что параметры OUT со значениями потенциально большого объема объявляются последними в списке параметров в инструкции SQL, используемой для создания SQLServerCallableStatement.Ensure that OUT parameters with potentially large values are declared last in the list of parameters in the SQL used to create the SQLServerCallableStatement. Кроме того, убедитесь в том, что методы get<Type>Stream класса SQLServerCallableStatement используются для доступа к параметрам OUT в порядке их объявления.In addition, ensure that the get<Type>Stream methods of the SQLServerCallableStatement are used to access the OUT parameters in the order they are declared.

  • Старайтесь не выполнять более одной инструкции относительно одного соединения одновременно.Avoid executing more than one statement on the same connection simultaneously. Выполнение другой инструкции до обработки результатов предыдущей инструкции может привести к тому, что необработанные результаты будут загружаться в память приложения.Executing another statement before processing the results of the previous statement may cause the unprocessed results to be buffered into the application memory.

  • В некоторых случаях использование selectMethod=cursor вместо responseBuffering=adaptive будет более полезным, например:There are some cases where using selectMethod=cursor instead of responseBuffering=adaptive would be more beneficial, such as:

    • если приложение медленно обрабатывает однопроходной результирующий набор только для чтения. Например, при считывании каждой строки после введения пользователем каких-то данных, использование selectMethod=cursor вместо responseBuffering=adaptive может уменьшить потребление ресурсов службой SQL ServerSQL Server.If your application processes a forward-only, read-only result set slowly, such as reading each row after some user input, using selectMethod=cursor instead of responseBuffering=adaptive might help reduce resource usage by SQL ServerSQL Server.

    • Если приложение обрабатывает два или более однопроходных результирующих набора только для чтения одновременно относительно одного подключения, использование selectMethod=cursor вместо responseBuffering=adaptive может уменьшить память, необходимую драйверу для обработки этих результирующих наборов.If your application processes two or more forward-only, read-only result sets at the same time on the same connection, using selectMethod=cursor instead of responseBuffering=adaptive might help reduce the memory required by the driver while processing these result sets.

    В обоих случаях необходимо учитывать чрезмерное потребление ресурсов при создании, считывании и закрытии серверных курсоров.In both cases, you need to consider the overhead of creating, reading, and closing the server cursors.

Помимо этого, в следующем списке приводятся рекомендации для прокручиваемых и однопроходных обновляемых результирующих наборов.In addition, the following list provides some recommendations for scrollable and forward-only updatable result sets:

  • Для прокручиваемых результирующих наборов при возвращении блока строк драйвер всегда считывает число строк, указанных методом getFetchSize объекта SQLServerResultSet, даже если включена адаптивная буферизация.For scrollable result sets, when fetching a block of rows the driver always reads into memory the number of rows indicated by the getFetchSize method of the SQLServerResultSet object, even when the adaptive buffering is enabled. Если прокручивание вызывает ошибку OutOfMemoryError, можно уменьшить число строк, возвращаемых при вызове метода setFetchSize объекта SQLServerResultSet, чтобы задать в качестве размера выборки меньшее число строк. При необходимости можно даже задать 1 строку.If scrolling causes an OutOfMemoryError, you can reduce the number of rows fetched by calling the setFetchSize method of the SQLServerResultSet object to set the fetch size to a smaller number of rows, even down to 1 row, if necessary. Если это не позволяет устранить ошибку OutOfMemoryError, старайтесь не включать столбцы очень большого объема в прокручиваемые результирующие наборы.If this does not prevent an OutOfMemoryError, avoid including very large columns in scrollable result sets.

  • Для однопроходных обновляемых результирующих наборов при возвращении блока строк драйвер обычно считывает в память число строк, указанное методом getFetchSize объекта SQLServerResultSet, даже если для подключения включена адаптивная буферизация.For forward-only updatable result sets, when fetching a block of rows the driver normally reads into memory the number of rows indicated by the getFetchSize method of the SQLServerResultSet object, even when the adaptive buffering is enabled on the connection. Если вызов метода next объекта SQLServerResultSet приводит к ошибке OutOfMemoryError, можно уменьшить число возвращаемых строк, вызвав метод setFetchSize объекта SQLServerResultSet, чтобы задать в качестве размера выборки меньшее число строк. При необходимости можно даже задать 1 строку.If calling the next method of the SQLServerResultSet object results in an OutOfMemoryError, you can reduce the number of rows fetched by calling the setFetchSize method of the SQLServerResultSet object to set the fetch size to a smaller number of rows, even down to 1 row, if necessary. Можно также запретить драйверу помещать в буфер строки, вызвав метод setResponseBuffering объекта SQLServerStatement с параметром "adaptive", прежде чем выполнять инструкцию.You can also force the driver not to buffer any rows by calling the setResponseBuffering method of the SQLServerStatement object with "adaptive" parameter before executing the statement. Так как результирующий набор не является прокручиваемым, если приложение получает доступ к значению столбца большого объема при помощи одного из методов get<Type>Stream, драйвер отбрасывает значение, как только приложение его считывает, так же как это происходит в случае с однопроходными результирующими наборами только для чтения.Because the result set is not scrollable, if the application accesses a large column value by using one of the get<Type>Stream methods, the driver discards the value as soon as the application reads it just as it does for the forward-only read-only result sets.

См. также разделSee also

Повышение производительности и надежности с помощью JDBC DriverImproving performance and reliability with the JDBC driver