sql >> Databáze >  >> RDS >> Oracle

Uložená procedura Oracle, vrací referenční kurzor vs asociativní pole

Požadavek DBA nedává smysl.

DBA si téměř jistě myslí, že chce minimalizovat počet změn kontextu modulu SQL na PL/SQL, které probíhají, když načítáte data z kurzoru. Navrhované řešení je však na tento konkrétní problém špatně zaměřeno a ve většině systémů přináší další mnohem závažnější problémy s výkonem.

V Oracle dochází k posunu kontextu SQL na PL/SQL, když virtuální počítač PL/SQL požádá virtuální počítač SQL o další data, virtuální počítač SQL odpoví dalším provedením příkazu, aby získal data, která pak zabalí a předá zpět PL. /SQL VM. Pokud stroj PL/SQL požaduje řádky jeden po druhém a vy načítáte mnoho řádků, je možné, že tyto posuny kontextu mohou představovat významnou část vašeho celkového běhového času. Aby se vypořádal s tímto problémem, zavedl Oracle koncept hromadných operací nejméně v 8i dnech. To umožnilo virtuálnímu počítači PL/SQL požadovat od virtuálního počítače SQL více řádků najednou. Pokud virtuální počítač PL/SQL požaduje 100 řádků najednou, eliminovali jste 99 % posunů kontextu a váš kód potenciálně běží mnohem rychleji.

Jakmile byly zavedeny hromadné operace, existovalo mnoho kódu, který bylo možné refaktorovat, aby byl efektivnější explicitním použitím BULK COLLECT operace spíše než načítání řádek po řádku a následné použití FORALL smyčky pro zpracování dat v těchto kolekcích. Do 10,2 dne však Oracle integroval hromadné operace do implicitního FOR smyčky, takže implicitní FOR smyčka nyní automaticky hromadně shromažďuje v dávkách po 100 namísto načítání řádek po řádku.

Ve vašem případě je však použití hromadných operací mnohem méně významné, protože data vracíte do klientské aplikace. Každé slušné rozhraní API na straně klienta bude mít funkcionalitu, která klientovi umožní určit, kolik řádků je třeba načíst z kurzoru v každém síťovém cyklu a tyto požadavky na načtení půjdou přímo do virtuálního počítače SQL, nikoli přes PL. /SQL VM, takže se nemusíte obávat žádných změn kontextu SQL na PL/SQL. Vaše aplikace se musí starat o načtení příslušného počtu řádků v každé zpáteční cestě – dost na to, aby aplikace nebyla příliš upovídaná a úzká v síti, ale ne tolik, abyste museli čekat příliš dlouho na výsledky. vrátit nebo uložit příliš mnoho dat do paměti.

Vrácení kolekcí PL/SQL spíše než REF CURSOR do klientské aplikace nesníží počet změn kontextu, ke kterým dojde. Ale bude to mít spoustu dalších nevýhod, z nichž v neposlední řadě je využití paměti. Kolekce PL/SQL musí být zcela uložena v procesní globální oblasti (PGA) (za předpokladu připojení k vyhrazenému serveru) na databázovém serveru. Toto je část paměti, která musí být přidělena z RAM serveru. To znamená, že server bude muset alokovat paměť, ve které bude načítat každý poslední řádek, který každý klient požaduje. To zase dramaticky omezí škálovatelnost vaší aplikace a v závislosti na konfiguraci databáze může ukrást RAM z jiných částí databáze Oracle, což by bylo velmi užitečné pro zlepšení výkonu aplikace. A pokud vám dojde místo PGA, vaše relace začnou dostávat chyby související s pamětí. Dokonce i v čistě PL/SQL aplikacích byste nikdy nechtěli načítat všechna data do kolekcí, vždy byste je chtěli načítat v menších dávkách, abyste minimalizovali množství PGA, které používáte.

Navíc načítání všech dat do paměti způsobí, že aplikace bude mnohem pomalejší. Téměř každý framework vám umožní načítat data, jak potřebujete, takže například pokud máte sestavu, kterou zobrazujete na stránkách po 25 řádcích, vaše aplikace by potřebovala načíst pouze prvních 25 řádků, než nakreslíte první obrazovka. A nikdy by nemuselo načítat dalších 25 řádků, pokud by uživatel náhodou nepožádal o další stránku výsledků. Pokud však načítáte data do polí, jak to navrhuje váš DBA, budete muset načíst všechny řádky, než vaše aplikace začne zobrazovat první řádek, i když uživatel nikdy nechce vidět více než první hrstku řádky. To bude znamenat mnohem více I/O na databázovém serveru pro načtení všech řádků, více PGA na serveru, více RAM na aplikačním serveru pro uložení výsledku a delší čekání na síť.



  1. Dynamické spouštění SQL na serveru SQL

  2. Pořadí sloupců ve vícesloupcovém indexu v MySQL

  3. gem install pg nefunguje na OSX Lion

  4. Jak lze dočasně deaktivovat omezení cizích klíčů pomocí T-SQL?