Share via


Adaptieve buffering gebruiken

JDBC-stuurprogramma downloaden

Adaptieve buffering is ontworpen om elk soort gegevens met een grote waarde op te halen zonder de overhead van servercursors. Toepassingen kunnen gebruikmaken van de functie adaptieve buffering met alle versies van SQL Server die door het stuurprogramma worden ondersteund.

Normaal gesproken haalt het stuurprogramma, wanneer het Microsoft JDBC-stuurprogramma voor SQL Server een query uitvoert, alle resultaten van de server op in het toepassingsgeheugen. Hoewel met deze benadering het resourceverbruik op de SQL Server wordt geminimaliseerd, kan er een OutOfMemoryError worden geretourneerd in de JDBC-toepassing voor de query's die zeer grote resultaten opleveren.

Om toepassingen in staat te stellen zeer grote resultaten te verwerken, biedt het Microsoft JDBC-stuurprogramma voor SQL Server adaptieve buffering. Met adaptieve buffering haalt het stuurprogramma uitvoeringsresultaten van de instructie op van de SQL Server naarmate de toepassing deze nodig heeft, in plaats van allemaal tegelijk. Het stuurprogramma negeert ook de resultaten zodra de toepassing deze niet meer kan openen. Hier volgen enkele voorbeelden waarbij de adaptieve buffering nuttig kan zijn:

  • De query produceert een zeer grote resultatenset: De toepassing kan een SELECT-instructie uitvoeren die meer rijen produceert dan de toepassing in het geheugen kan opslaan. In eerdere versies moest de toepassing een servercursor gebruiken om een OutOfMemoryError te voorkomen. Adaptieve buffering biedt de mogelijkheid om een uitsluitend-vooruit alleen-lezen doorgang uit te voeren van een resultaatset van willekeurige grootte zonder dat er een servercursor nodig is.

  • De query produceert zeer groteSQLServerResultSet-kolommenofSQLServerCallableStatementOUT-parameterwaarden: de toepassing kan één waarde (kolom- of OUT-parameter) ophalen die te groot is om volledig in het toepassingsgeheugen te passen. Met adaptieve buffering kan de clienttoepassing een dergelijke waarde als een stream ophalen met behulp van de getAsciiStream-, de getBinaryStream- of de getCharacterStream-methoden. De toepassing haalt de waarde op uit de SQL Server terwijl deze uit de stream wordt gelezen.

Opmerking

Met adaptieve buffering buffert het JDBC-stuurprogramma alleen de hoeveelheid gegevens die het moet. Het stuurprogramma biedt geen openbare methode om de grootte van de buffer te beheren of te beperken.

Adaptieve buffering instellen

Vanaf het JDBC-stuurprogramma versie 2.0 is het standaardgedrag van het stuurprogramma 'adaptief'. Met andere woorden, om het adaptieve buffergedrag op te halen, hoeft uw toepassing het adaptieve gedrag niet expliciet aan te vragen. In de release van versie 1.2 was de buffermodus echter standaard 'vol' en moest de toepassing expliciet de modus voor adaptieve buffering aanvragen.

Er zijn drie manieren waarop een toepassing kan aanvragen dat de instructieuitvoering gebruikmaakt van adaptieve buffering:

Wanneer u het JDBC-stuurprogramma versie 1.2 gebruikt, moeten toepassingen het instructieobject casten naar een SQLServerStatement-klasse om de methode setResponseBuffering te gebruiken. In de codevoorbeelden in de voorbeeld met het lezen van grote gegevens en de voorbeeld met het lezen van grote gegevens met opgeslagen procedures wordt dit oude gebruik gedemonstreerd.

Met het JDBC-stuurprogramma versie 2.0 kunnen toepassingen echter de isWrapperFor-methode en de methode uitpakken gebruiken om toegang te krijgen tot de leverancierspecifieke functionaliteit zonder enige aanname over de hiërarchie van implementatieklassen. Zie de voorbeeldcode in de sectie bijwerken van grote gegevens.

Grote gegevens ophalen met adaptieve buffering

Wanneer grote waarden eenmaal worden gelezen met behulp van de<get Type>Stream-methoden, en de kolommen ResultSet en de CallableStatement OUT-parameters worden geopend in de volgorde die wordt geretourneerd door de SQL Server, minimaliseert adaptieve buffering het geheugengebruik van de toepassing bij het verwerken van de resultaten. Wanneer u adaptieve buffering gebruikt:

  • <De get Type>Stream-methoden die zijn gedefinieerd in de klassen SQLServerResultSet en SQLServerCallableStatement retourneren standaard read-once streams, hoewel de streams opnieuw kunnen worden ingesteld als ze door de toepassing worden gemarkeerd. Als de toepassing de stream wil reset , moet deze eerst de mark methode voor die stream aanroepen.

  • <De get Type>Stream-methoden die zijn gedefinieerd in de klassen SQLServerClob en SQLServerBlob, retourneren streams die altijd naar de beginpositie van de stream kunnen worden verplaatst zonder de mark methode aan te roepen.

Wanneer de toepassing adaptieve buffering gebruikt, kunnen de waarden die worden opgehaald door de<get Type>Stream-methoden slechts eenmaal worden opgehaald. Als u een get Type-methode< probeert aan te roepen>in dezelfde kolom of parameter nadat u de<get Type>Stream-methode van hetzelfde object hebt aangeroepen, wordt er een uitzondering gegenereerd met het bericht 'De gegevens zijn geopend en zijn niet beschikbaar voor deze kolom of parameter'.

Opmerking

Een aanroep naar ResultSet.close() tijdens de verwerking van een ResultSet vereist dat het Microsoft JDBC-stuurprogramma voor SQL Server alle resterende pakketten leest en verwerpt. Dit kan veel tijd duren als de query een grote gegevensset heeft geretourneerd en vooral als de netwerkverbinding traag is.

Richtlijnen voor het gebruik van adaptieve buffering

Ontwikkelaars moeten deze belangrijke richtlijnen volgen om het geheugengebruik door de toepassing te minimaliseren:

  • Vermijd het gebruik van de eigenschap selectMethod=cursor van de verbindingsreeks om toe te staan dat de toepassing een zeer grote resultatenset verwerkt. Met de functie voor adaptieve buffering kunnen toepassingen zeer grote alleen-lezen resultatensets verwerken zonder een servercursor te gebruiken. Houd er rekening mee dat wanneer u selectMethod=cursor instelt, alle voorwaarts-alleen, alleen-lezen resultatensets die door die verbinding geproduceerd worden, beïnvloed worden. Met andere woorden, als uw toepassing regelmatig korte resultatensets verwerkt met een paar rijen, maakt, leest en sluitt u een servercursor voor elke resultatenset, gebruikt u meer resources aan zowel clientzijde als serverzijde dan het geval is wanneer de selectMethod niet is ingesteld op cursor.

  • Lees grote tekst- of binaire waarden als streams met behulp van de getAsciiStream-, getBinaryStream- of getCharacterStream-methoden in plaats van de getBlob- of getClob-methoden. Vanaf de release van versie 1.2 biedt de klasse SQLServerCallableStatement nieuwe Get<Type>Stream-methoden voor dit doel.

  • Zorg ervoor dat kolommen met mogelijk grote waarden als laatste worden geplaatst in de lijst met kolommen in een SELECT-instructie en dat de<get Type>Stream-methoden van de SQLServerResultSet worden gebruikt voor toegang tot de kolommen in de volgorde waarin ze zijn geselecteerd.

  • Zorg ervoor dat OUT-parameters met mogelijk grote waarden als laatste worden gedeclareerd in de lijst met parameters in de SQL die worden gebruikt om de SQLServerCallableStatement te maken. Zorg er bovendien voor dat de<get Type>Stream-methoden van de SQLServerCallableStatement worden gebruikt voor toegang tot de OUT-parameters in de volgorde waarin ze worden gedeclareerd.

  • Vermijd het tegelijkertijd uitvoeren van meer dan één instructie op dezelfde verbinding. Het uitvoeren van een andere instructie voordat de resultaten van de vorige instructie worden verwerkt, kan ertoe leiden dat de niet-verwerkte resultaten in het toepassingsgeheugen worden gebufferd.

  • Er zijn enkele gevallen waarin het gebruik van selectMethod=cursor in plaats van responseBuffering=adaptive nuttiger zou zijn, zoals:

    • Als uw toepassing een alleen-vooruit, alleen-lezen resultatenset langzaam verwerkt, zoals wanneer elke rij wordt gelezen na enige gebruikersinvoer, kan het gebruik van selectMethod=cursor in plaats van responseBuffering=adaptive helpen om het resourcegebruik door SQL Server te verminderen.

    • Als uw toepassing twee of meer alleen-doorsturende, alleen-lezen resultatensets op hetzelfde moment op dezelfde verbinding verwerkt, kan het gebruik van selectMethod=cursor in plaats van responseBuffering=adaptive mogelijk helpen het geheugen te verminderen dat door het stuurprogramma vereist is tijdens het verwerken van deze resultatensets.

    In beide gevallen moet u rekening houden met de overhead van het maken, lezen en sluiten van de servercursors.

Daarnaast geeft de volgende lijst enkele aanbevelingen voor scrollbare en alleen vooruit bij te werken resultatensets.

  • Bij het ophalen van een blok rijen leest het stuurprogramma altijd in het geheugen het aantal rijen dat wordt aangegeven door de getFetchSize-methode van het OBJECT SQLServerResultSet , zelfs wanneer de adaptieve buffering is ingeschakeld voor scrollbare resultatensets. Als schuiven een OutOfMemoryError veroorzaakt, kunt u het aantal rijen verminderen dat wordt opgehaald door de methode setFetchSize van het SQLServerResultSet-object aan te roepen om de ophaalgrootte in te stellen op een kleiner aantal rijen, zelfs tot 1 rij, indien nodig. Als hiermee geen OutOfMemoryError wordt voorkomen, vermijdt u het opnemen van zeer grote kolommen in schuifbare resultatensets.

  • Bij alleen vooruit bijwerkbare resultaatsets leest het stuurprogramma normaal gesproken in het geheugen het aantal rijen dat wordt aangegeven door de getFetchSize-methode van het SQLServerResultSet-object wanneer er een blok rijen wordt opgehaald, zelfs als de adaptieve buffering is ingeschakeld op de verbinding. Als u de volgende methode van het object SQLServerResultSet aanroept in een OutOfMemoryError, kunt u het aantal rijen dat is opgehaald verminderen door de methode setFetchSize van het SQLServerResultSet-object aan te roepen om de ophaalgrootte in te stellen op een kleiner aantal rijen, zelfs tot 1 rij, indien nodig. U kunt ook afdwingen dat het stuurprogramma geen rijen buffert door de methode setResponseBuffering van het SQLServerStatement-object aan te roepen met de parameter Adaptief voordat u de instructie uitvoert. Omdat de resultaatset niet scrollbaar is, verwijdert het stuurprogramma de waarde zodra de applicatie toegang krijgt tot een grote kolomwaarde met behulp van een van de< get Type>Stream-methoden, net zoals het doet voor de alleen-doorsturen, alleen-lezen resultaatsets.

Zie ook

Prestaties en betrouwbaarheid verbeteren met het JDBC-stuurprogramma