Искането на DBA няма смисъл.
Това, което DBA почти сигурно мисли, е, че той иска да минимизира броя на промените в контекста на SQL към PL/SQL двигателя, които се случват, когато извличате данни от курсор. Но решението, което се предлага, е слабо насочено към този конкретен проблем и въвежда други много по-сериозни проблеми с производителността в повечето системи.
В Oracle изместване на контекста от SQL към PL/SQL възниква, когато PL/SQL VM поиска от SQL VM повече данни, SQL VM отговаря, като изпълни оператора допълнително, за да получи данните, които след това пакетира и връща обратно на PL /SQL VM. Ако PL/SQL машината иска редове един по един и вие извличате много редове, възможно е тези промени в контекста да представляват значителна част от общото ви време на изпълнение. За да се бори с този проблем, Oracle въведе концепцията за групови операции поне през 8i дни. Това позволи на PL/SQL VM да поиска няколко реда наведнъж от SQL VM. Ако PL/SQL VM изисква 100 реда наведнъж, вие сте елиминирали 99% от промените в контекста и вашият код потенциално ще работи много по-бързо.
След като груповите операции бяха въведени, имаше много код, който можеше да бъде преработен, за да бъде по-ефективен чрез изрично използване на BULK COLLECT
операции, вместо да извлича ред по ред и след това да използва FORALL
цикли за обработка на данните в тези колекции. До 10,2 дни обаче Oracle интегрира групови операции в имплицитно FOR
цикли, така че имплицитно FOR
цикълът вече автоматично групово събира в партиди от 100, вместо да извлича ред по ред.
Във вашия случай обаче, тъй като връщате данните към клиентско приложение, използването на групови операции е много по-малко значимо. Всеки приличен API от страна на клиента ще има функционалност, която позволява на клиента да посочи колко реда трябва да бъдат извлечени от курсора при всяко мрежово пътуване и тези заявки за извличане ще отидат директно до SQL VM, а не през PL /SQL VM, така че няма измествания на контекста от SQL към PL/SQL, за които да се притеснявате. Вашето приложение трябва да се грижи за извличането на подходящ брой редове при всяко двупосочно пътуване-- достатъчно, за да не стане твърде бърбориво и тясно място в мрежата, но не толкова много, че да трябва да чакате твърде дълго, за да бъдат резултатите върнат или да съхранява твърде много данни в паметта.
Връщането на PL/SQL колекции вместо REF CURSOR към клиентско приложение няма да намали броя на изместванията на контекста, които се случват. Но ще има куп други недостатъци, не на последно място, използването на паметта. PL/SQL колекция трябва да се съхранява изцяло в глобалната област на процеса (PGA) (приемайки връзки със специален сървър) на сървъра на базата данни. Това е част от паметта, която трябва да бъде разпределена от RAM на сървъра. Това означава, че сървърът ще трябва да разпредели памет, в която да извлече всеки последен ред, който всеки клиент поиска. Това от своя страна ще ограничи драстично скалируемостта на вашето приложение и, в зависимост от конфигурацията на базата данни, може да открадне RAM от други части на базата данни на Oracle, което би било много полезно за подобряване на производителността на приложението. И ако ви свърши PGA пространството, вашите сесии ще започнат да получават грешки, свързани с паметта. Дори в приложения, базирани изцяло на PL/SQL, никога не бихте искали да извличате всички данни в колекции, винаги бихте искали да ги извличате на по-малки партиди, за да минимизирате количеството PGA, което използвате.
В допълнение, извличането на всички данни в паметта ще направи приложението много по-бавно. Почти всяка рамка ще ви позволи да извличате данни, когато имате нужда от тях, така че, например, ако имате отчет, който показвате на страници от 25 реда всяка, вашето приложение ще трябва да извлече само първите 25 реда, преди да рисува първи екран. И никога не би трябвало да извлича следващите 25 реда, освен ако потребителят случайно не поиска следващата страница с резултати. Ако обаче извличате данните в масиви, както предлага вашият DBA, ще трябва да извлечете всички редове, преди приложението ви да започне да показва първия ред, дори ако потребителят никога не иска да вижда повече от първата шепа от редове. Това ще означава много повече I/O на сървъра на базата данни за извличане на всички редове, повече PGA на сървъра, повече RAM на сървъра на приложения за буфериране на резултата и по-дълго чакане за мрежата.