Tema: mySQL view
Pogledajte određenu poruku
Staro 12. 06. 2008.   #14
Dejan Topalovic
old school
Professional
 
Datum učlanjenja: 15.02.2006
Lokacija: Wien, Austria
Poruke: 304
Hvala: 121
47 "Hvala" u 26 poruka
Dejan Topalovic će postati "faca" uskoro
Pošaljite poruku preko MSN za Dejan Topalovic
Default

Citat:
Originalno napisao DejanVesic Pogledajte poruku
Ako mislite na običan View nad tabelama, osnovno sredstvo rada u bazama podataka.
Osnovno sredstvo rada u bazi su tabele.

Citat:
Originalno napisao DejanVesic Pogledajte poruku
Prvo, NIKAD Order By u samom pogledu; time terate SQL engine (koji god da je u pitanju) da pravi privremenu tabelu i sortira je (naravno, ako ovo nije pogled nad jednom tabelom i Order By je nad kolonom koja ima indeks).

ORDER By uvek radite iz klijent koda.

(ta rečenica upravo to znači: ako uradite Order By iz klijentskog koda, uzeće se taj Order By a ne definicija iz pogleda).
Da li si siguran u tu tvrdnju?
Evo rezultat jednog malog testa, koristeci tabelu sa oko 300 000 redova:

createview test_view_no_order
asselect * fromtb_benchmark_data_m;

createview test_view_with_order
asselect * fromtb_benchmark_data_morderby bm_date;
select * from test_view_with_order;
select * from test_view_no_order;
declare
vrijeme_na_startu number;

begin
sys.dbms_support.start_trace(true,true);
-- prvo upit na test_view_no_order da podaci budu u cache-u:
for rec in(select * from test_view_no_order)
loop
null;
endloop;
-- zatim upit na test_view_no_order sa ORDER BY:
vrijeme_na_startu := dbms_utility.get_time;
for rec in(select * from test_view_no_order orderby bm_date)
loop
null;
endloop;

dbms_output.put_line
('Vrijeme trajanja za ''test_view_no_order'' sa ORDER BY: '|| to_char((dbms_utility.get_time- vrijeme_na_startu)/100) ||' sekundi');
-- zatim upit na test_view_with_order bez ORDER BY:
vrijeme_na_startu := dbms_utility.get_time;
for rec in(select * from test_view_with_order)
loop
null;
endloop;

dbms_output.put_line
('Vrijeme trajanja za ''test_view_with_order'' bez ORDER BY: '|| to_char((dbms_utility.get_time- vrijeme_na_startu)/100) ||' sekundi');

sys
.dbms_support.stop_trace;
end;


Rezultat izgleda ovako:

Citat:
Vrijeme trajanja za 'test_view_no_order' sa ORDER BY: 3,75 sekundi
Vrijeme trajanja za 'test_view_with_order' bez ORDER BY: 3,44 sekundi

Vrijeme trajanja za 'test_view_no_order' sa ORDER BY: 4,3 sekundi
Vrijeme trajanja za 'test_view_with_order' bez ORDER BY: 3,41 sekundi

Vrijeme trajanja za 'test_view_no_order' sa ORDER BY: 4,14 sekundi
Vrijeme trajanja za 'test_view_with_order' bez ORDER BY: 3,95 sekundi

Vrijeme trajanja za 'test_view_no_order' sa ORDER BY: 3,91 sekundi
Vrijeme trajanja za 'test_view_with_order' bez ORDER BY: 3,67 sekundi
Znaci prilikom svakog izvrsavanja je opcija VIEW sa ORDER BY bila brza od opcije VIEW sa klijentskim ORDER BY.

Evo jos rezultat internog funkcionisanja u Oracle bazi:

Kôd:
SELECT * 
FROM
 TEST_VIEW_NO_ORDER

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch    10536      7.17       5.79          0      39637          0     1053351
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10542      7.17       5.79          0      39637          0     1053351
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 57     (recursive depth: 1)
********************************************************************************
SELECT * 
FROM
 TEST_VIEW_NO_ORDER ORDER BY BM_DATE

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch    10536     11.31       8.98          0      29391          0     1053351
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10542     11.31       8.98          0      29391          0     1053351
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 57     (recursive depth: 1)
********************************************************************************
SELECT * 
FROM
 TEST_VIEW_WITH_ORDER

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        3      0.00       0.00          0          0          0           0
Execute      3      0.00       0.00          0          0          0           0
Fetch    10536     10.59       8.43          0      29391          0     1053351
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total    10542     10.59       8.43          0      29391          0     1053351
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 57     (recursive depth: 1)
********************************************************************************
Nadam se da je iz ovog testa vidljivo, da je VIEW sa ugradjenim ORDER BY brzi od VIEW sa ORDER BY NA klijentskoj strani...

Citat:
Originalno napisao DejanVesic Pogledajte poruku
Treće, korišćenjem View-a dajete šansu SQL enginu da uradi optimizaciju plana pristupa podacima (ili eksplicitno, nekom komandom, ili implicitno) i/ili prekompajliranje definicije pogleda u neki interni jezik, tako da se podacima pristupa brže i efikasnije.
Netacno, barem kod Oraclea. Ako se koristi materialized views sa opcijom "query rewrite enabled", onda baza interno moze da izvrsi optimizaciju upita, ali sa obicnim viewom to nije moguce.

Citat:
Originalno napisao DejanVesic Pogledajte poruku
Četvrto, kada god možete, koristite bind varijable za definisanje kriterijuma za izdvajanje podataka; znači, umesto da lepite eksplicitne vrednosti u SQL uplit:

"Select * From Products_V where IDProduct = 23"

koristite:

"Select * From Products_V where IDProduct = :1"

a zatim i odgovarajući način za jezik / platformu da date vrednost parametru :1
Ovo je tacno i to je veoma bitna stvar, koja uveliko utice na performanse.
__________________
Blog: Baze podataka
------------------------
Oracle OCP DBA
Oracle OCE SQL Expert
Oracle OCP Developer
Certified MySQL DBA
Dejan Topalovic je offline   Odgovorite uz citat
2 članova zahvaljuje Dejan Topalovic za poruku: