[ obucina @ 01.09.2005. 15:57 ] @
Mislio sam da je ovo greška u optimizaciji upita na Firebird-u,
ali sam dobio odgovor da nije. Dakle, u pseudo kodu:

create procedure (param integer)
begin
for select * from table t
where (:param is null) or (t.field = :param)
suspend;
end

Namera je da se omogući da procedura vrati sve slogove ako parametar nije prosleđen.
Mogući su i drugi uslovi u WHERE klauzuli. SELECT je veliki, ima po 5-6 JOIN-a i tri elementa UNION.

Kada je parametar prosleđen, dobijam neindeksirana čitanja svih slogova u tabeli,
što rezultuje katastrofalno sporim izvršavanjem (300000 neindeksiranih čitanja,
naspram ~150 indeksiranih koliko mi je potrebno).

Kako rešavate slične situacije, tj kako bi omogućili pomenuto ponašanje procedure?
Zbog veličine SELECT-a, ne dolazi u obzir nešto tipa

if param is null then
for select *
else
for select *



[Ovu poruku je menjao obucina dana 01.09.2005. u 17:01 GMT+1]
[ obucina @ 01.09.2005. 20:56 ] @
Ovo nije samo Firebird pitanje i zato ga nisam ni postavio ovde.
Znao sam da ce moderator da mi premesti pitanje cim sam napisao Firebird.
[ sosingus @ 07.09.2005. 08:33 ] @
Zasto ne proveris koja su ti polja ne indexsirana, pa indexsiras?
A postoji i jedna zgodna naredba nisam jos stigla da je isprobam, ali su mogucnosti sa njom mnogo vece - moze da ti pomogne.
Code:
[for] execute statement <string> [into :param1 , ... , :paramn] [do]

Tako da mozes dinamicki sklopiti select statement npr.
Code:
sql = 'select ';
if (param is null) then
  uslov = '  '
else
  uslov = 'where ...  ';
...
sql = sql || uslov;
execute statement sql /* u obliku koji ti treba */

Ovde imas detalje
http://www.destructor.de/firebird/1.5/execute_statement.txt
[ Riste Pejov @ 12.09.2005. 18:32 ] @
[rant]
zelim ubrzati moj auto koji ima 4 tockova i volan!
[/rant]

Niko ti ne moze pomoci ako ne das ERD i full stored proc. Jedino sto ti mogu reci je da detaljno analiziras execution plan, pa da onda krenes analiticki da diseciras selecte i sigurno ces stici do nekog prihvatljivog resenja.