Massinsamling med LIMIT-klausul i Oracle-databasen
Hittills har vi lärt oss hur man förbättrar frågeprestanda med hjälp av bulk collect med SELECT-INTO som använder den implicita markören och FETCH-INTO-satsen för en explicit markör. Men frågan kvarstår om det fortfarande finns utrymme för ytterligare frågeoptimering? I den här bloggen kommer vi att lära oss hur vi kan förbättra vår fråga ytterligare med hjälp av Limit-klausulen med massinsamling?
Vi har redan lärt oss processen att komprimera flera switchar genom att använda bulk collect med select-in och i sin tur få större kontroll över frågan genom att använda densamma med en fetch-into-sats av en explicit markör. Men det finns fortfarande ett problem som kräver vår uppmärksamhet och det är överdriven minnesutmattning orsakad av massinsamling.
Vad menar du med överdriven minnesutmattning orsakad av massinsamling?
Varje gång vi hämtar eller hämtar ett stort antal poster med hjälp av bulk collect-klausulen börjar vårt program förbruka mycket minne för att vara snabbt och effektivt. Detta är inte vilket minne som helst. Till skillnad från SGA-minnet som delas mellan alla sessioner i Oracle Database, förbrukar programmet PGA-minnet som är specifikt tilldelat för varje session.
Detta försämrar prestandan hos databasen. Det betyder att vår sökfråga säkert måste fungera bra, men samtidigt kanske inte vår databas.
Vi kan inte ha en väloptimerad fråga genom att äventyra prestandan för hela vår databas. Visst?
Hur kan vi lösa problemet med minnesutmattning genom massinsamling?
Detta problem med minnesutmattning kan lätt övervinnas om vi kan kontrollera och begränsa mängden data som hämtas med hjälp av massinsamlingen. Vi kan göra det genom att använda Bulk Collect med LIMIT-satsen.
Vad är syntaxen för LIMIT-satsen?
LIMIT-satsen fungerar som ett attribut för en FETCH-INTO-sats:
FETCH <cursor_name> BULK COLLECT INTO <plsql_collection> LIMIT number;
Eftersom LIMIT fungerar som ett attribut för FETCH-INTO-satsen, så för att använda den kan du lägga till nyckelordet LIMIT följt av en specifik siffra som kommer att specificera antalet rader som bulk-collect-satsen kommer att hämta på en gång i slutet av FETCH -INTO uttalande.
Vad gör LIMIT-satsen?
LIMIT-satsen begränsar antalet rader som hämtas med BULK COLLECT med FETCH-satsen.
Kan vi använda LIMIT-satsen med SELECT-INTO-satsen?
Nej, vi kan inte använda LIMIT-satsen med SELECT-INTO-satsen. LIMIT-satsen fungerar som ett attribut till FETCH-INTO-satsen eftersom LIMIT-satsen kräver en explicit markör för att fungera och FETCH-INTO-satsen är en del av explicit markörens livscykel.
Så kom alltid ihåg att LIMIT-satsen endast kan användas när du använder BULK COLLECT med FETCH-INTO-satsen. Det kan inte användas när du använder bulk collect med SELECT-INTO-satsen.
Exempel:Hur man använder LIMIT-satsen med Bulk Collect-satsen i Oracle Database
Här är ett mycket enkelt exempel som visar hur du kan arbeta med LIMIT-satsen.
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; /
Du kan se videohandledningen på min YouTube-kanal för en detaljerad förklaring av koden ovan.
Så den här gången istället för att hämta alla poster och uttömma en dyr resurs som minne, tack vare LIMIT-klausulen, hämtar vi bara de nödvändiga raderna och det också utan resursslöseri. På så sätt kan vi ta vår frågeprestanda ett snäpp högre med massinsamling.
Så nu frågar du, Manish vad är rätt antal rader vi kan hämta?
För att veta svaret på denna fråga föreslår jag att du läser den här bloggen av min kära vän Steven Feuerstein på Oracles hemsida. Han har svarat på denna fråga riktigt bra.
Det finns också en brist med detta tillvägagångssätt och det är:Om du kör samma program igen, kommer denna FETCH-INTO-sats med LIMIT-sats inte att lägga till samlingen med nästa 10 poster. Snarare kommer den att trunkera tabellen och fylla i den kapslade tabellen igen från index nr.1.
Min kära vän Connor McDonald har gjort en blogg som förklarar hur du kan lösa detta problem med MULTISET. Gå vidare och kolla in hans artikel.
Det är den detaljerade PL/SQL-bloggen om hur man använder LIMIT-klausulen med Bulk Collect i Oracle Database. Hoppas du tyckte om att läsa, om så är fallet, se till att dela den här handledningen med dina vänner på dina sociala medier. Tack för att du läser. Ha en bra dag!