sql >> Database teknologi >  >> RDS >> Oracle

Oracle lagret procedure, returnerer ref markør vs associative arrays

DBA's anmodning giver ikke mening.

Hvad DBA næsten helt sikkert tænker er, at han ønsker at minimere antallet af SQL til PL/SQL-motorkontekstskift, der foregår, når du henter data fra en markør. Men den løsning, der bliver foreslået, er dårligt målrettet mod dette særlige problem og introducerer andre meget mere alvorlige ydeevneproblemer i de fleste systemer.

I Oracle sker et SQL til PL/SQL kontekstskift, når PL/SQL VM beder SQL VM om flere data, SQL VM reagerer ved at udføre sætningen yderligere for at få dataene, som den derefter pakker sammen og sender tilbage til PL /SQL VM. Hvis PL/SQL-motoren beder om rækker én ad gangen, og du henter mange rækker, er det muligt, at disse kontekstskift kan være en betydelig brøkdel af din samlede kørselstid. For at bekæmpe dette problem introducerede Oracle konceptet med bulkoperationer tilbage i det mindste i 8i-dagene. Dette gjorde det muligt for PL/SQL VM'en at anmode om flere rækker ad gangen fra SQL VM'en. Hvis PL/SQL VM anmoder om 100 rækker ad gangen, har du elimineret 99 % af kontekstskiftene, og din kode kører potentielt meget hurtigere.

Når bulk-operationer blev introduceret, var der en masse kode, der kunne refaktoriseres for at blive mere effektiv ved eksplicit at bruge BULK COLLECT handlinger i stedet for at hente række-for-række og derefter bruge FORALL sløjfer til at behandle dataene i disse samlinger. Inden de 10,2 dage havde Oracle imidlertid integreret bulkoperationer i implicit FOR sløjfer så en implicit FOR løkke samler nu automatisk masseindsamling i batches af 100 i stedet for at hente række-for-række.

I dit tilfælde, da du returnerer dataene til en klientapplikation, er brugen af ​​masseoperationer dog meget mindre væsentlig. Enhver anstændig klientside API vil have funktionalitet, der lader klienten specificere, hvor mange rækker der skal hentes fra markøren i hver netværksrundtur, og disse hentningsanmodninger vil gå direkte til SQL VM, ikke gennem PL /SQL VM, så der er ingen SQL til PL/SQL kontekstskift at bekymre sig om. Din applikation skal bekymre sig om at hente et passende antal rækker i hver rundrejse - nok til at applikationen ikke bliver for snakkesalig og flaskehals på netværket, men ikke så mange, at du skal vente for længe på, at resultaterne er returneret eller for at gemme for mange data i hukommelsen.

At returnere PL/SQL-samlinger i stedet for en REF CURSOR til en klientapplikation vil ikke reducere antallet af kontekstskift, der finder sted. Men det vil have en masse andre ulemper, ikke mindst hukommelsesbrug. En PL/SQL-samling skal gemmes helt i det globale procesområde (PGA) (forudsat dedikerede serverforbindelser) på databaseserveren. Dette er en del af hukommelsen, der skal allokeres fra serverens RAM. Det betyder, at serveren bliver nødt til at allokere hukommelse til at hente hver sidste række, som hver klient anmoder om. Det vil til gengæld dramatisk begrænse skalerbarheden af ​​din applikation og, afhængigt af databasekonfigurationen, kan det stjæle RAM væk fra andre dele af Oracle-databasen, hvilket ville være meget nyttigt til at forbedre applikationens ydeevne. Og hvis du løber tør for PGA-plads, vil dine sessioner begynde at få hukommelsesrelaterede fejl. Selv i rent PL/SQL-baserede applikationer ville du aldrig ønske at hente alle data ind i samlinger, du vil altid gerne hente dem i mindre batches for at minimere mængden af ​​PGA, du bruger.

Derudover vil det at hente alle data i hukommelsen få applikationen til at føles meget langsommere. Næsten alle rammer vil give dig mulighed for at hente data, som du har brug for det, så hvis du for eksempel har en rapport, som du viser på sider med 25 rækker hver, skal din applikation kun hente de første 25 rækker, før du maler første skærm. Og det ville aldrig skulle hente de næste 25 rækker, medmindre brugeren tilfældigvis anmodede om den næste side med resultater. Hvis du henter dataene ind i arrays, som din DBA foreslår, bliver du dog nødt til at hente alle rækkerne, før din applikation kan begynde at vise den første række, selvom brugeren aldrig ønsker at se mere end den første håndfuld af rækker. Det vil betyde meget mere I/O på databaseserveren for at hente alle rækkerne, mere PGA på serveren, mere RAM på applikationsserveren for at buffere resultatet og længere ventetid på netværket.



  1. Oracle:SQL-forespørgsel, der returnerer rækker med kun numeriske værdier

  2. Sådan formateres tal som valuta i MySQL

  3. Sådan løses FATAL:forbindelsesgrænsen er overskredet for ikke-superbrugere

  4. Null reference fra MySQL driver modul fra taskpane.js en Microsoft Office Add-In