Żądanie administratora baz danych nie ma sensu.
DBA prawie na pewno myśli, że chce zminimalizować liczbę przesunięć kontekstu silnika SQL do PL/SQL, które mają miejsce podczas pobierania danych z kursora. Ale sugerowane rozwiązanie jest słabo ukierunkowane na ten konkretny problem i wprowadza inne, znacznie poważniejsze problemy z wydajnością w większości systemów.
W Oracle zmiana kontekstu z SQL na PL/SQL występuje, gdy PL/SQL VM prosi SQL VM o więcej danych, SQL VM odpowiada, wykonując instrukcję dalej, aby uzyskać dane, które następnie pakuje i przekazuje z powrotem do PL /SQL maszyna wirtualna. Jeśli aparat PL/SQL prosi o wiersze pojedynczo i pobierasz wiele wierszy, możliwe, że te przesunięcia kontekstu mogą stanowić znaczną część ogólnego środowiska uruchomieniowego. Aby rozwiązać ten problem, Oracle wprowadziło koncepcję operacji masowych co najmniej w dniach 8i. Umożliwiło to maszynie wirtualnej PL/SQL żądanie wielu wierszy naraz z maszyny wirtualnej SQL. Jeśli maszyna wirtualna PL/SQL żąda 100 wierszy na raz, wyeliminowałeś 99% zmian kontekstu, a Twój kod może działać znacznie szybciej.
Po wprowadzeniu operacji zbiorczych istniało wiele kodów, które można było zrefaktoryzować, aby zwiększyć wydajność, używając jawnego BULK COLLECT
operacji zamiast pobierania wiersz po wierszu, a następnie używania FORALL
pętle do przetwarzania danych w tych kolekcjach. Jednak do 10.2 dnia firma Oracle zintegrowała operacje zbiorcze z niejawnym FOR
pętle, więc niejawny FOR
pętla teraz automatycznie zbiera zbiorczo w partiach po 100, zamiast pobierać wiersz po wierszu.
Jednak w Twoim przypadku, ponieważ zwracasz dane do aplikacji klienckiej, użycie operacji zbiorczych jest znacznie mniej istotne. Każdy przyzwoity interfejs API po stronie klienta będzie miał funkcjonalność, która pozwoli klientowi określić, ile wierszy ma zostać pobranych z kursora w każdej sieci w obie strony, a te żądania pobrania będą trafiać bezpośrednio do maszyny wirtualnej SQL, a nie przez PL /SQL VM, więc nie trzeba się martwić o zmiany kontekstu z SQL na PL/SQL. Twoja aplikacja musi się martwić o pobranie odpowiedniej liczby wierszy w każdej podróży w obie strony — wystarczy, że aplikacja nie stanie się zbyt gadatliwa i nie stanie się wąskim gardłem w sieci, ale nie tak wiele, że trzeba będzie czekać zbyt długo na wyniki zwrócone lub przechowywać zbyt dużo danych w pamięci.
Zwracanie kolekcji PL/SQL zamiast REF CURSOR do aplikacji klienckiej nie zmniejszy liczby zachodzących zmian kontekstu. Ale będzie miał wiele innych wad, z których nie najmniej ważnym jest użycie pamięci. Zbiór PL/SQL musi być przechowywany w całości w obszarze globalnym procesu (PGA) (przy założeniu połączeń z dedykowanym serwerem) na serwerze bazy danych. Jest to porcja pamięci, która musi zostać przydzielona z pamięci RAM serwera. Oznacza to, że serwer będzie musiał przydzielić pamięć, z której będzie mógł pobrać każdy ostatni wiersz, którego żąda każdy klient. To z kolei drastycznie ograniczy skalowalność aplikacji i, w zależności od konfiguracji bazy danych, może wykraść pamięć RAM z innych części bazy danych Oracle, co byłoby bardzo przydatne w poprawie wydajności aplikacji. A jeśli zabraknie Ci miejsca na PGA, w Twoich sesjach zaczną pojawiać się błędy związane z pamięcią. Nawet w aplikacjach opartych wyłącznie na PL/SQL, nigdy nie chciałbyś pobierać wszystkich danych do kolekcji, zawsze chciałbyś pobierać je w mniejszych partiach, aby zminimalizować ilość używanego PGA.
Ponadto pobranie wszystkich danych do pamięci znacznie spowolni działanie aplikacji. Prawie każda struktura pozwoli Ci pobierać dane w miarę potrzeb, więc na przykład, jeśli masz raport, który wyświetlasz na stronach po 25 wierszy każda, Twoja aplikacja będzie musiała pobrać tylko pierwsze 25 wierszy przed malowaniem pierwszy ekran. I nigdy nie musiałby pobierać kolejnych 25 wierszy, chyba że użytkownik przypadkiem zażądał kolejnej strony wyników. Jeśli jednak pobierasz dane do tablic, tak jak proponuje DBA, będziesz musiał pobrać wszystkie wiersze, zanim aplikacja zacznie wyświetlać pierwszy wiersz, nawet jeśli użytkownik nigdy nie chce widzieć więcej niż pierwsza garść wydziwianie. Będzie to oznaczać dużo więcej operacji we/wy na serwerze bazy danych w celu pobrania wszystkich wierszy, więcej PGA na serwerze, więcej pamięci RAM na serwerze aplikacji do buforowania wyników i dłuższe oczekiwanie na sieć.