konto usunięte

Temat: Oracle - pomiar czasu wykonania procedury w ms

Witam

Mam następujący problem z Oracle. Potrzebuje zmierzyć czas wykonania w ms procedury o nazwie SELECTQUERY. Wykorzystuje do tego inna procedurę o nazwie TIMEEXECUTION. Poniżej zamieszczam ich kody:

*****************************************************************

create or replace PROCEDURE TIMEEXECUTION
( nazwaprocedury IN VARCHAR2
, wynik OUT NUMBER) AS

strt timestamp;
stp timestamp;

BEGIN

SELECT systimestamp INTO strt FROM dual;

EXECUTE IMMEDIATE 'BEGIN ' || nazwaprocedury || '; END;';

SELECT systimestamp INTO stp FROM dual;

wynik := (to_number(to_char(stp,'hh24')) * 3600000000 + to_number(to_char(stp,'MI')) * 60000 + to_number(to_char(stp,'SS')) * 1000 + to_number(substr(to_char(stp,'FF'),1,3)))
- (to_number(to_char(strt,'hh24')) * 3600000000 + to_number(to_char(strt,'MI')) * 60000 + to_number(to_char(strt,'SS')) * 1000 + to_number(substr(to_char(strt,'FF'),1,3)));


END TIMEEXECUTION;

****************************************************************

create or replace
PROCEDURE SELECTQUERY AS


BEGIN

EXECUTE IMMEDIATE 'SELECT * FROM EKSPERYMENTWARTOSC';

END SELECTQUERY;

*****************************************************************

Problem polega na tym, iż czas wykonania procedury SELECTQUERY zmierzony przez TIMEEXECUTION wynosi 0. Oracle tak jakby nie wykonywał w ogóle polecenia EXECUTE IMMEDIATE 'SELECT * FROM EKSPERYMENTWARTOSC'; z procedury SELECTQUERY. Dla innych procedur, w których wykonywane są inne polecenia (insert, update, select into itd.) czas wykonania jest > 0 i jest poprawnie mierzony.

Proponowany model mierzenia czasu wykonania SELECTA poprzez procedure SELECTQUERY zastosowałem w 3 innych DBMS (MS SQL, MySQL oraz PostgreSQL) i problem tam taki nie występuje. Selecty w procedurze są wykonywane (czas wykonania polecenia >> 0).

Czy ma ktoś jakiś pomysł jak to obejść ? Potrzebuje zwrócić czas wykonania selecta (SELECT * FROM EKSPERYMENTWARTOSC) z poziomu bazy ORACLE do programu w C#.

Dziękuje i pozdrawiam

TW
Lukasz K.

Lukasz K. Communication &
Public Speaking
Consultant

Temat: Oracle - pomiar czasu wykonania procedury w ms

create or replace
PROCEDURE SELECTQUERY AS

BEGIN

EXECUTE IMMEDIATE 'SELECT * FROM EKSPERYMENTWARTOSC';

END SELECTQUERY;

Proponuje przetestowac taki kod:

EXECUTE IMMEDIATE 'SELECT * FROM EKSPERYMENTWARTOSC' INTO zmienna;

gdzie zmienna jest odpowiednim typem danych zwracanym przez tego selecta (jakie kolumny/kolumna kryja sie pod gwiazdka?)

jeszcze mozna to rozwiazac REF CURSORem
a dlaczego ten select nie moze zostac wrzucony normalnie do PL/SQLa tylko musi byc w dynamic zrobiony?Lukasz K. edytował(a) ten post dnia 15.05.10 o godzinie 21:18

konto usunięte

Temat: Oracle - pomiar czasu wykonania procedury w ms

Samo zapytanie ma głęboko ukryty sens, bo nie zwraca żadnej wartości, więc może zostać zignorowane
Jeżeli wykonujesz takie zapytanie wiele razy, to jego wyniki mogą zostać zbuforowane..... Tym bardziej jeśli tabela jest mała... Nie ma żadnego warunku na where, czyli pobierane są rekordy jakie się "nawiną"...
Wg mnie - jeśli tabela EKSPERYMENTWARTOSC jest mała,to nic nie zdziałasz....Jeśli jest duża dodaj where z warunkami na losowo generowane klucze do selekcji i dodaj jakieś FETCH-owanie..
W ogóle używanie w ten sposób kodu z EXECUTE IMMEDIATE doskonale zaciemnia kod, bo pozbawia Ciebie np. kontroli składniowej..., co będzie jeśli taki kod zostanie przeprowadzony do innego schematu??
Zamiast tego zdefiniuj cursor z ograniczeniem jakie będziesz urzywać w rzeczywistych warunkach,
i w pętli dokonaj pobrania danych z cursora do zmiennej typu
EKSPERYMENTWARTOSC%ROWTYPE

PROCEDURE SELECTQUERY AS
CURSOR vc_El IS SELECT * FROM EKSPERYMENTWARTOSC WHERE -- Twój warunek
vr_El_EKSPERYMENTWARTOSC%ROWTYPE;
BEGIN
FOR EL IN vc_El
LOOP
vr_El := EL;
END LOOP;
END;

---
pisałem z głowy mogłem się pomylić w kodzie
Grzegorz D.

Grzegorz D. PL/SQL Developer

Temat: Oracle - pomiar czasu wykonania procedury w ms

Czy możliwe jest, żeby takie wywołanie zostało zignorowane?
Przeprowadziłem testy dla jakiejś tabeli 750 tys rekordów.
Przy wywołaniu takim jak w procce - wynik 0. Przy dodaniu into zmienna - wynik pojawia się normalnie.

edit: po sprawdzeniu innych tabel - za pierwszym razem wyrzucal jakis wynik, pozniej juz 0, wiec byc moze to cache?Grzegorz Drzymała edytował(a) ten post dnia 15.05.10 o godzinie 22:30
Marcin Zieliński

Marcin Zieliński Autoryzowane
szkolenia Oracle i
IBM

Temat: Oracle - pomiar czasu wykonania procedury w ms

CREATE TABLE duza
AS SELECT LEVEL AS id FROM dual CONNECT BY LEVEL < 750000;

DECLARE
t1 TIMESTAMP;
t2 TIMESTAMP;
BEGIN
SELECT systimestamp INTO t1 FROM dual;
EXECUTE IMMEDIATE 'select * from duza';
SELECT systimestamp INTO t2 FROM dual;
Dbms_Output.put_line(t2-t1);
END;
/

SELECT * FROM v$sql WHERE Upper(sql_text) LIKE '%DUZA%';

Nie ignoruje, ale robi (za pierwszym razem) tylko parsowanie + generowanie planu - bez fetcha - zwróć uwagę na kolumny PARSE_CALLS, EXECUTIONS oraz FETCHES.

Za pierwszym razem wartość jest na tyle duża, że może się coś pojawić - później już korzysta z shared pool więc niewiele (poza sprawdzeniem sql_id) nie robi - co zajmuje mniej niż 10e-6 sekundy stąd w wyniku wartość 0.

Aha - żeby była jasność - bez INTO nie mierzy Ci czasu wykonania (tak jak go rozumiesz) bo nie pobierasz danych. Niestety - kursory niewiele Ci pomogą zmierzyć - bo możesz uzyskać niemiarodajny wynik.

Aby zmierzyć czas faktyczny zapytania wywołanego w C (kilka czynników może spowodować ze robiąc select * from tabela w C i np. w sql plusie uzyskasz inne wyniki) proponuję:

ALTER SYSTEM FLUSH shared_pool;
ALTER SYSTEM FLUSH buffer_cache;
-- wywołanie programu w C czytającego tabelkę DUZA
SELECT sql_text, elapsed_time/1000000 FROM v$sql WHERE Upper(sql_text) LIKE '%DUZA%';

Z tym, że mierzenie czasu w ten sposób też może być niemiarodajne bo dotyczy tylko bazy i zależy jak w rzeczywistości Ci się bufory poukładają. Moja propozycja zmierzy wariant pesymistyczny - cache pusty.

A najlepiej - zmierz czas w C# - dzięki temu zmierzysz narzut sterownika i jakichś bibliotek.

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 16.05.10 o godzinie 00:13
Grzegorz D.

Grzegorz D. PL/SQL Developer

Temat: Oracle - pomiar czasu wykonania procedury w ms

A może za pomocą sql plusa?


set timing on
set serveroutput off
set autotrace traceonly

select * from dwdm.actual_pivot;


Wynik:
13988 wierszy wybranych
Całkowity 00:00:00.46
Marcin Zieliński

Marcin Zieliński Autoryzowane
szkolenia Oracle i
IBM

Temat: Oracle - pomiar czasu wykonania procedury w ms

Grzegorz Drzymała:
A może za pomocą sql plusa?


set timing on
set serveroutput off
set autotrace traceonly

select * from dwdm.actual_pivot;


Wynik:
13988 wierszy wybranych
Całkowity 00:00:00.46

Przydatne, ale są pewne czynniki które sprawić mogą, że SQL*Plus wygeneruje zdecydowanie inne wyniki od rzeczywistego czasu
wykonania zapytania w innej aplikacji.

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 15.05.10 o godzinie 23:57

Temat: Oracle - pomiar czasu wykonania procedury w ms

Marcin Zieliński:
Grzegorz Drzymała:
A może za pomocą sql plusa?


set timing on
set serveroutput off
set autotrace traceonly

select * from dwdm.actual_pivot;


Wynik:
13988 wierszy wybranych
Całkowity 00:00:00.46

Przydatne, ale są pewne czynniki które sprawić mogą, że SQL*Plus wygeneruje zdecydowanie inne wyniki co czas wykonania zapytania w innej aplikacji.

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 15.05.10 o godzinie 23:48


Witam,

Z moich doswiadczen SQL*Plus wygeneruje najlepszy mozliwy czas.
Pozatym zgadzam sie w 100 % z tym stwierdzeniem Tanel-a Podera ktore zapisal Doug na swoim blogu - http://www.oracledoug.com/serendipity/index.php?/archi...

"- When diagnosing Oracle problems reported by others, I ask them to stop using TOAD, their JDBC application or whatever it is they're using and login to sqlplus. Once the problem is recreated there, I know it's a real problem."

pozdrawiam,
Marcin
Marcin Zieliński

Marcin Zieliński Autoryzowane
szkolenia Oracle i
IBM

Temat: Oracle - pomiar czasu wykonania procedury w ms


Witam,

Z moich doswiadczen SQL*Plus wygeneruje najlepszy mozliwy czas.

Nie twierdzę, że wynik w innej aplikacji będzie lepszy - raczej w
drugą stronę, chociaż jest masa czynników, które to determinują - w każdym razie może być zdecydowanie inny.

Z cytatem właściwie się zgadzam - bo dla nas problem jest wtedy gdy jest on po stronie bazy :)

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 16.05.10 o godzinie 00:08
Wojtek Jurewicz

Wojtek Jurewicz ETL and Database
Developer / Business
Intelligence
specia...

Temat: Oracle - pomiar czasu wykonania procedury w ms

Marcin Zieliński:
proponuję:

ALTER SYSTEM FLUSH shared_pool;
ALTER SYSTEM FLUSH buffer_cache;
-- wywołanie programu w C czytającego tabelkę DUZA
SELECT sql_text, elapsed_time/1000000 FROM v$sql WHERE Upper(sql_text) LIKE '%DUZA%';

Z tym, że mierzenie czasu w ten sposób też może być niemiarodajne bo dotyczy tylko bazy i zależy jak w rzeczywistości Ci się bufory poukładają. Moja propozycja zmierzy wariant pesymistyczny - cache pusty.

Powtórzenie testu wielokrotnie i wyciągnięcie średniej zmniejszy udział czynników "losowych" takich jak obłożenie buforów.
Marcin Zieliński

Marcin Zieliński Autoryzowane
szkolenia Oracle i
IBM

Temat: Oracle - pomiar czasu wykonania procedury w ms

Wojtek Jurewicz:

Powtórzenie testu wielokrotnie i wyciągnięcie średniej zmniejszy udział czynników "losowych" takich jak obłożenie buforów.

TEORETYCZNIE masz racje, ale wpływ środowiska jakie masz dla konkretnego zapytania czyni problem bardziej skomplikowanym. Oczywiście zawsze średnia lepsza niż jedna (i co gorsza pierwsza) próba.

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 19.05.10 o godzinie 22:31
Wojtek Jurewicz

Wojtek Jurewicz ETL and Database
Developer / Business
Intelligence
specia...

Temat: Oracle - pomiar czasu wykonania procedury w ms

Marcin Zieliński:
Oczywiście zawsze średnia lepsza niż jedna (i co gorsza pierwsza) próba.

Właśnie to chyba - jak zwykle - zależy. ;-) Każda kolejna próba korzysta z shared pool i cache-u, pytanie czy przypadkiem nie interesuje nas czas wykonania niebuforowanego zapytania. Taki test powinien być zrobiony tak, żeby jednak za każdym razem sięgnął do dysku - może nie koniecznie każdorazowo konstruował plan wykonania, chociaż z tego co wiem, DBMS poświęca względnie mało czasu na konstrukcję planu w stosunku do przewidywanego czasu wykonania a przy większej ilości danych i bardziej skomplikowanych zapytaniach czas ten może okazać się znaczący - I/O powinny zająć znaczną część czasu niwelując tym samym wpływ innych czynników.

Wydaje się jednak, że co do stanu środowiska i jego dostrojenia, można brnąć w temat sporo dalej - bo przecież aplikacje w tle również korzystają z dysku, system operacyjny dzieli czas procesora po swojemu itp. - pytanie czy na potrzeby tego testu jest sens?
Piotr B.

Piotr B. Handlarz też
człowiek

Temat: Oracle - pomiar czasu wykonania procedury w ms

Foglight Performance Analysis for Oracle
Marcin Zieliński

Marcin Zieliński Autoryzowane
szkolenia Oracle i
IBM

Temat: Oracle - pomiar czasu wykonania procedury w ms

Wojtek Jurewicz:

Wydaje się jednak, że co do stanu środowiska i jego dostrojenia, można brnąć w temat sporo dalej - bo przecież aplikacje w tle również korzystają z dysku, system operacyjny dzieli czas procesora po swojemu itp. - pytanie czy na potrzeby tego testu jest sens?

Ale ja nie mówiłem tylko o buforach. Konfiguracja środowiska może być zupełnie inna co oznacza, że nawet przy tych samych stanach buforów i takim samym obciążeniu w tle wyniki mogą być skrajnie różne w sql plusie i w rzeczywistej aplikacji.

PozdrawiamMarcin Zieliński edytował(a) ten post dnia 25.05.10 o godzinie 09:14
Kamil Stawiarski

Kamil Stawiarski Oracle Certified
Master | Oracle ACE

Temat: Oracle - pomiar czasu wykonania procedury w ms

Witam,
polecam przyjrzeć się pakietowi DBMS_PROFILER - powinien dostarczyć wszystkich interesujących informacji na temat czasu wykonania i lokalizacji wąskich gardeł.

Przykład chociażby tutaj: http://antognini.ch/papers/dbms_profiler_20000818.pdf

Pozdrawiam.

Następna dyskusja:

Badanie czasu dostepu do re...




Wyślij zaproszenie do