Udostępnij przez


Korzystanie z buforowania adaptacyjnego

pobierz sterownik JDBC

Buforowanie adaptacyjne zaprojektowano tak, aby pobierać wszelkiego rodzaju dane o dużych rozmiarach bez obciążeń kursory serwera. Aplikacje mogą używać funkcji adaptacyjnego buforowania ze wszystkimi wersjami programu SQL Server obsługiwanymi przez sterownik.

Zwykle, gdy sterownik JDBC firmy Microsoft dla programu SQL Server wykonuje zapytanie, sterownik pobiera wszystkie wyniki z serwera do pamięci aplikacji. Mimo że takie podejście minimalizuje zużycie zasobów w programie SQL Server, może on zgłosić błąd OutOfMemoryError w aplikacji JDBC dla zapytań, które generują bardzo duże wyniki.

Aby umożliwić aplikacjom obsługę bardzo dużych wyników, sterownik JDBC firmy Microsoft dla programu SQL Server zapewnia buforowanie adaptacyjne. W przypadku buforowania adaptacyjnego sterownik pobiera wyniki wykonywania instrukcji z programu SQL Server, ponieważ aplikacja ich potrzebuje, a nie jednocześnie. Sterownik odrzuca również wyniki, gdy tylko aplikacja nie będzie mogła uzyskać do nich dostępu. Poniżej przedstawiono kilka przykładów, w których buforowanie adaptacyjne może być przydatne:

  • Zapytanie generuje bardzo duży zestaw wyników: Aplikacja może wykonać instrukcję SELECT, która generuje więcej wierszy niż aplikacja może przechowywać w pamięci. W poprzednich wersjach aplikacja musiała używać kursora serwera, aby uniknąć błędu OutOfMemoryError. Adaptacyjne buforowanie umożliwia jednokierunkowe, tylko do odczytu przetwarzanie dowolnie dużego zestawu wyników bez konieczności używania kursora serwera.

  • Zapytanie generuje bardzo duże kolumny SQLServerResultSet lub SQLServerCallableStatement OUT wartości parametrów: aplikacja może pobrać pojedynczą wartość (kolumna lub parametr OUT), która jest zbyt duża, aby całkowicie zmieścić się w pamięci aplikacji. Buforowanie adaptacyjne umożliwia aplikacji klienckiej pobieranie takiej wartości jako strumienia przy użyciu metody getAsciiStream, getBinaryStream lub getCharacterStream. Aplikacja pobiera wartość z SQL Server podczas odczytu ze strumienia.

Uwaga / Notatka

W przypadku buforowania adaptacyjnego sterownik JDBC buforuje tylko ilość danych, które musi buforować. Sterownik nie udostępnia żadnej publicznej metody kontrolowania ani ograniczania rozmiaru buforu.

Ustawianie buforowania adaptacyjnego

Począwszy od sterownika JDBC w wersji 2.0, domyślne zachowanie sterownika jest "adaptacyjne". Innymi słowy, aby uzyskać zachowanie adaptacyjnego buforowania, aplikacja nie musi jawnie żądać zachowania adaptacyjnego. Jednak w wersji 1.2 tryb buforowania był domyślnie "pełny", a aplikacja musiała jawnie zażądać trybu adaptacyjnego buforowania.

Aplikacja może zażądać wykonania instrukcji z użyciem buforowania adaptacyjnego na trzy sposoby:

W przypadku korzystania ze sterownika JDBC w wersji 1.2 aplikacje musiały rzutować obiekt wyrażenia do klasy SQLServerStatement, aby użyć metody setResponseBuffering. Przykłady kodu w przykładzie odczytywania dużego zestawu danych i przykładzie odczytywania dużych danych za pomocą procedur składowanych demonstrują to stare zastosowanie.

Jednak w przypadku sterownika JDBC w wersji 2.0 aplikacje mogą używać metody isWrapperFor i metody unwrap , aby uzyskać dostęp do funkcji specyficznych dla dostawcy bez żadnych założeń dotyczących hierarchii klas implementacji. Przykładowy kod można znaleźć w temacie Aktualizowanie przykładowych danych .

Pobieranie dużych danych przy użyciu buforowania adaptacyjnego

Gdy duże wartości są odczytywane jednorazowo za pomocą metod get<Type>Stream, a kolumny ResultSet i parametry OUT instrukcji CallableStatement są dostępne w kolejności zwracanej przez SQL Server, buforowanie adaptacyjne minimalizuje zużycie pamięci aplikacji podczas przetwarzania wyników. W przypadku korzystania z buforowania adaptacyjnego:

  • Metody get<Type>Stream zdefiniowane w klasach SQLServerResultSet i SQLServerCallableStatement domyślnie zwracają strumienie, które można odczytać tylko raz, choć mogą zostać zresetowane, jeśli aplikacja oznaczy je do zresetowania. Jeśli aplikacja chce strumienia reset , najpierw musi wywołać metodę mark w tym strumieniu.

  • Metody get<Type>Stream zdefiniowane w klasach SQLServerClob i SQLServerBlob zwracają strumienie, które zawsze można przywrócić do pozycji początkowej bez wywoływania mark metody.

Gdy aplikacja korzysta z buforowania adaptacyjnego, wartości pobierane przez metody get<Type>Stream można pobrać tylko raz. Jeśli spróbujesz wywołać dowolną metodę get<Type> w tej samej kolumnie lub parametrze po wywołaniu metody get<Type>Stream na tym samym obiekcie, zostanie zgłoszony wyjątek z komunikatem "Dane zostały odczytane i nie są dostępne dla tej kolumny lub parametru".

Uwaga / Notatka

Wywołanie elementu ResultSet.close() w trakcie przetwarzania elementu ResultSet wymagałoby, aby sterownik JDBC firmy Microsoft dla programu SQL Server odczytywał i odrzucał wszystkie pozostałe pakiety. Może to zająć dużo czasu, jeśli zapytanie zwróciło duży zestaw danych, a zwłaszcza jeśli połączenie sieciowe jest powolne.

Wskazówki dotyczące używania buforowania adaptacyjnego

Deweloperzy powinni postępować zgodnie z tymi ważnymi wskazówkami, aby zminimalizować użycie pamięci przez aplikację:

  • Unikaj używania właściwości parametrów połączenia selectMethod=cursor , aby umożliwić aplikacji przetwarzanie bardzo dużego zestawu wyników. Funkcja adaptacyjnego buforowania umożliwia aplikacjom przetwarzanie bardzo dużych zestawów wyników tylko do odczytu bez użycia kursora serwera. Należy pamiętać, że po ustawieniu selectMethod=cursor, wszystkie zestawy wyników tylko do odczytu generowane przez to połączenie są tym dotknięte. Innymi słowy, jeśli aplikacja rutynowo przetwarza krótkie zestawy wyników z kilkoma wierszami, tworzenie, odczytywanie i zamykanie kursora serwera dla każdego zestawu wyników będzie używać więcej zasobów po stronie klienta i po stronie serwera niż w przypadku, gdy selectMethod nie jest ustawiony na kursor.

  • Odczytywanie dużych wartości tekstowych lub binarnych jako strumieni przy użyciu metody getAsciiStream, getBinaryStream lub getCharacterStream zamiast metody getBlob lub getClob. Począwszy od wersji 1.2, klasa SQLServerCallableStatement udostępnia nowe metody getTypeStream w tym celu.

  • Upewnij się, że kolumny z potencjalnie dużymi wartościami znajdują się na ostatniej liście kolumn w instrukcji SELECT i że metody get<Type>Stream zestawu SQLServerResultSet są używane do uzyskiwania dostępu do kolumn w kolejności ich wybrania.

  • Upewnij się, że parametry OUT z potencjalnie dużymi wartościami są deklarowane jako ostatnie na liście parametrów w języku SQL używanym do utworzenia elementu SQLServerCallableStatement. Ponadto upewnij się, że metody getTypeStream klasy SQLServerCallableStatement są używane do uzyskiwania dostępu do parametrów OUT w kolejności ich deklaracji.

  • Unikaj jednoczesnego wykonywania więcej niż jednej instrukcji na tym samym połączeniu. Wykonanie innej instrukcji przed przetworzeniem wyników poprzedniej instrukcji może spowodować buforowanie nieprzetworzonych wyników do pamięci aplikacji.

  • W niektórych przypadkach użycie polecenia selectMethod=cursor zamiast responseBuffering=adaptive byłoby bardziej korzystne, na przykład:

    • Jeśli Twoja aplikacja przetwarza zestaw wyników tylko do odczytu i przetwarza go powoli, przykładowo odczytując każdy wiersz po wprowadzeniu danych przez użytkownika, użycie ustawienia selectMethod=cursor zamiast responseBuffering=adaptive może pomóc zmniejszyć użycie zasobów przez serwera SQL Server.

    • Jeśli twoja aplikacja przetwarza co najmniej dwa zestawy wyników jednokierunkowych, tylko do odczytu jednocześnie na tej samej sesji, użycie selectMethod=cursor zamiast responseBuffering=adaptive może pomóc zmniejszyć wymaganą pamięć przez sterownik podczas przetwarzania tych zestawów wyników.

    W obu przypadkach należy rozważyć obciążenie związane z tworzeniem, odczytywaniem i zamykaniem kursorów serwera.

Ponadto poniższa lista zawiera kilka zaleceń dotyczących zestawów wyników z możliwością przewijania i aktualizowania tylko do przodu:

  • W przypadku zestawów wyników z możliwością przewijania podczas pobierania bloku wierszy sterownik zawsze odczytuje do pamięci liczbę wierszy wskazanych przez metodę getFetchSize obiektu SQLServerResultSet , nawet gdy jest włączone buforowanie adaptacyjne. Jeśli przewijanie powoduje błąd OutOfMemoryError, możesz zmniejszyć liczbę wierszy pobranych przez wywołanie metody setFetchSize obiektu SQLServerResultSet w celu ustawienia rozmiaru pobierania na mniejszą liczbę wierszy, nawet w razie potrzeby do 1 wiersza. Jeśli nie zapobiegnie to błędowi OutOfMemoryError, unikaj dołączania bardzo dużych kolumn w zestawach wyników z możliwością przewijania.

  • W przypadku zestawów wyników z możliwością aktualizacji tylko do przodu, podczas pobierania bloku wierszy sterownik zwykle odczytuje do pamięci liczbę wierszy wskazywanych przez metodę getFetchSize obiektu SQLServerResultSet , nawet gdy adaptacyjne buforowanie jest włączone w połączeniu. Jeśli wywołanie następnej metody obiektu SQLServerResultSet powoduje błąd OutOfMemoryError, można zmniejszyć liczbę wierszy pobranych przez wywołanie metody setFetchSize obiektu SQLServerResultSet w celu ustawienia rozmiaru pobierania na mniejszą liczbę wierszy, nawet w razie potrzeby do 1 wiersza. Można również wymusić, aby sterownik nie buforował żadnych wierszy, wywołując metodę setResponseBuffering obiektu SQLServerStatement z parametrem "adaptacyjnym" przed wykonaniem instrukcji. Ponieważ zestaw wyników nie jest przewijany, jeśli aplikacja uzyskuje dostęp do dużej wartości kolumny przy użyciu jednej z metod get<Type>Stream, sterownik odrzuca wartość zaraz po jej odczytaniu przez aplikację, tak jak ma to miejsce w przypadku przesuwnych tylko do odczytu zestawów wyników.

Zobacz także

Zwiększanie wydajności i niezawodności dzięki sterownikowi JDBC