sql >> Database >  >> RDS >> Oracle

PL/SQL Bulk Collect met LIMIT-clausule in Oracle Database

Bulkverzameling met LIMIT-clausule in Oracle Database

Tot nu toe hebben we geleerd hoe we de prestaties van query's kunnen verbeteren met behulp van bulkcollect met SELECT-INTO die de impliciete cursor en de FETCH-INTO-instructie van een expliciete cursor gebruikt. Maar de vraag blijft of er nog ruimte is voor verdere query-optimalisatie? In deze blog leren we hoe we onze zoekopdracht verder kunnen verbeteren met behulp van de Limit-clausule met bulkcollect?

We hebben al het proces geleerd van het comprimeren van meerdere schakelaars door bulkcollect te gebruiken met select-in en op zijn beurt meer controle over de query te krijgen door hetzelfde te gebruiken met een fetch-in-instructie van een expliciete cursor. Maar er is nog steeds een probleem dat onze aandacht vereist en dat is overmatige geheugenuitputting veroorzaakt door bulkverzameling.

Wat bedoel je met overmatige geheugenuitputting veroorzaakt door bulkverzameling?

Telkens wanneer we een groot aantal records ophalen of ophalen met behulp van de bulkcollect-clausule, begint ons programma veel geheugen te verbruiken om snel en efficiënt te zijn. Dit is niet zomaar een herinnering. In tegenstelling tot het SGA-geheugen dat door alle sessies van Oracle Database wordt gedeeld, verbruikt het programma het PGA-geheugen dat specifiek voor elke sessie is toegewezen.

Dit verslechtert de prestaties van de database. Dit betekent dat onze zoekopdracht zeker goed moet presteren, maar tegelijkertijd misschien niet.

We kunnen geen goed geoptimaliseerde query hebben door de prestaties van onze hele database in gevaar te brengen. Toch?

Hoe kunnen we dit probleem van geheugenuitputting door bulkverzameling oplossen?

Dit probleem van geheugenuitputting kan gemakkelijk worden overwonnen als we de hoeveelheid gegevens die worden opgehaald met behulp van bulkverzameling kunnen controleren en beperken. We kunnen dat doen door Bulk Collect te gebruiken met de LIMIT-clausule.

Wat is de syntaxis van de LIMIT-clausule?

LIMIT-clausule werkt als een attribuut van een FETCH-INTO-instructie:

FETCH <cursor_name> BULK COLLECT INTO <plsql_collection> LIMIT number;

Aangezien LIMIT werkt als een attribuut van de FETCH-INTO-instructie, dus om het te gebruiken, kunt u het trefwoord LIMIT toevoegen, gevolgd door een specifiek numeriek cijfer dat het aantal rijen specificeert dat de bulk-collect-clausule in één keer aan het einde van FETCH zal ophalen -INTO-instructie.

Wat doet de LIMIT-clausule?

De LIMIT-clausule beperkt het aantal rijen dat wordt opgehaald met de instructie BULK COLLECT met de instructie FETCH.

Kunnen we de LIMIT-clausule gebruiken met de SELECT-INTO-instructie?

Nee, we kunnen de LIMIT-clausule niet gebruiken met de SELECT-INTO-instructie. De LIMIT-clausule werkt als een attribuut voor de FETCH-INTO-instructie omdat de LIMIT-clausule een expliciete cursor vereist om te werken en de FETCH-INTO-instructie een onderdeel is van de expliciete cursorlevenscyclus.

Onthoud dus altijd dat de LIMIT-clausule alleen kan worden gebruikt wanneer u BULK COLLECT gebruikt met de instructie FETCH-INTO. Het kan niet worden gebruikt wanneer u bulkcollect gebruikt met de instructie SELECT-INTO.

Voorbeeld:het gebruik van de LIMIT-clausule met de Bulk Collect-instructie in Oracle Database

Hier is een heel eenvoudig voorbeeld dat u laat zien hoe u met de LIMIT-clausule kunt werken.

SET SERVEROUTPUT ON;
DECLARE
    CURSOR exp_cur IS
    SELECT first_name FROM employees;
    
    TYPE nt_fName   IS TABLE OF VARCHAR2(20);
    fname   nt_fName;
BEGIN
    OPEN exp_cur;
    FETCH exp_cur   BULK COLLECT INTO fname     LIMIT 10;
    CLOSE exp_cur;
    --Print data
    FOR idx IN 1 .. fname.COUNT
    LOOP
        DBMS_OUTPUT.PUT_LINE (idx||' '||fname(idx) );
    END LOOP;
END;
/

Je kunt de video-tutorial op mijn YouTube-kanaal raadplegen voor de gedetailleerde uitleg van de bovenstaande code.

Dus in plaats van alle records op te halen en een dure bron zoals geheugen uit te putten, halen we deze keer dankzij de LIMIT-clausule alleen de noodzakelijke rijen op en dat ook zonder enige verspilling van bronnen. Op deze manier kunnen we onze queryprestaties naar een hoger niveau tillen met bulkverzameling.

Dus nu vraag je, Manish, wat is het juiste aantal rijen dat we kunnen ophalen?

Om het antwoord op deze vraag te weten, raad ik je aan om deze blog van mijn dierbare vriend Steven Feuerstein op de website van Oracle te lezen. Hij heeft deze vraag heel goed beantwoord.

Er is ook een tekortkoming aan deze aanpak en dat is:als u hetzelfde programma opnieuw uitvoert, dan zal deze FETCH-INTO-instructie met LIMIT-clausule de verzameling niet toevoegen met de volgende 10 records. In plaats daarvan zal het de tabel afkappen en de geneste tabel opnieuw vullen vanuit index nr.1.

Mijn goede vriend Connor McDonald heeft een blog geschreven waarin hij uitlegt hoe je dit probleem kunt oplossen met MULTISET. Ga je gang en bekijk zijn artikel.

Dat is de gedetailleerde PL/SQL-blog over het gebruik van de LIMIT-clausule met Bulk Collect in Oracle Database. Ik hoop dat je het leuk vond om te lezen, als dat zo is, deel deze tutorial dan met je vrienden op je sociale media. Bedankt voor het lezen. Fijne dag!


  1. Hoe CONV() werkt in MariaDB

  2. Een script genereren op basis van een diagram in MySQL Workbench

  3. Webinar:bijhouden van queryvoortgang in SQL Server

  4. PostgreSQL:hoe te converteren van Unix-tijdperk tot nu toe?