Blog programisty w Oracle PL/SQL

Jest to blog eksperymentatora programisty w PL/SQL dla Oracle. Wszystkie kody tutaj zamieszczone mogą być dowolnie wykorzystywane i zmieniane. A jeśli Ktoś z Gości znajdzie błąd, będę niezwykle wdzięczny...
Zapisz

Szukaj na tym blogu

sobota, 8 stycznia 2011

Czy to Java czy C - porównanie wydajności procedur zewnętrznych w Windows

Całość eksperymentów przeprowadziłem na Oracle 11g 64 bit zainstalowanym na Windows 7.
Napisałem niezwykle prostą funkcję w C

int _stdcall sum(int x , int y)
{
return x+y;
}

Korzystając z kompilatora Microsoft Visual C++ opakowałem powyższą w bibliotekę DLL  na platformę x64( 32 bitowe biblioteki nie współdziałają z Oracle 64 bit), wygenerowałem plik test_dll.dll.
Kilka chwil zajęło zmuszenie listenera do współpracy, ale  przy odrobinie dobrych chęci nie jest to trudne. Natępnie podłączyłem zewnętrzny kod:
CREATE OR REPLACE LIBRARY MyC_LIB 
  AS 'D:\Projects\CPP\test_dll\Release\test_dll.dll';

CREATE OR REPLACE FUNCTION test_CSUM
(x BINARY_INTEGER, y BINARY_INTEGER
RETURN BINARY_INTEGER
AS LANGUAGE C
LIBRARY MyC_LIB
NAME "sum";

Następnie wykonałem zapytanie:
 
SELECT SUM(TEST_CSUM(2,1)) /3 FROM ALL_TAB_COLS
 Wynik z zapytania zwraca liczę rekordów z view: wynik 90451 rekordów został otrzymany w czasie 30 sekund. Wychodzi około 3 tysięcy wywołań rekordów na sekundę ..
Pokombinujmy, jeśli do definicji funkcji dodamy modyfikator DETERMINISTIC , to czas wykonania spadnie do 1s. Ale:
  • funkcje deterministyczne to szczególny przypadek i dosyć rzadki w przyrodzie
  • funkcje deterministyczne warto stosować, jeśli zbiór parametrów wejściowych jest niewielki, dla obliczeń numerycznych dla co najwyżej kilkunastotysięcznego zbioru parametrów wejściowych
  •  Oracle w przypadku zewnętrznych procedur nie zwróci nam uwagi, że wynik funkcji zależy od daty lub generatora liczb losowych
Mogłoby się wydawać, że natywne niskopoziomowe biblioteki DLL powinny być niezwykle szybkie, a jednak nie nadają się do wykorzystania w przypadku zapytań obrabiających  duże zbiory danych...

Wykonajmy analogiczny eksperyment z Java...
public class SumTest {
 public static int sum (int a, int b)
{
    return a+b;
    }
} 

Załadujmy klasę:
loadjava -thin -user  user/pwd@test d:\PLSQL\SumTest.java 
Dla Oracle 64 bit dla Windows loadjava działa tylko w wersji thin..

Kompilujemy pakiet i mapujemy funkcję

alter java class user."SumTest" compile;

CREATE OR REPLACE FUNCTION user.test_jsum
(a NUMBER, b Number)
RETURN NUMBER
AS
LANGUAGE JAVA
NAME 'SumTest.sum
(int, int) return int';


I sprawdzenie

SELECT SUM(TEST_JSUM(2,1)) /3 FROM ALL_TAB_COLS
Wynik  90451 rekordów pojawił się po 5 sekundach.. Jest pięć razy szybciej około 18 tysięcy rekordów na sekundę.. Dla niewielkich zbiorów danych można ścierpieć...
 Podsumowując: do przetwarzanie  masowego wielkich zbiorów danych funkcje zewnętrzne się nie nadają..  Najlepiej sprawdzają się w rzadkich i nieczęsto stosowanych przypadkach

Brak komentarzy:

Prześlij komentarz