Šta je novo?

Ako ima stručnjaka za SQL Server...

jddipqd

Čuven
Učlanjen(a)
17.10.2000
Poruke
2,555
Poena
725
Oduvek sam mislio da kada uslov u WHEREu sigurno postane tačan ili sigurno netačan (1 OR nesto ili 0 AND nesto) da se to nesto neće evaluirati.

Međutim, ispada da nije tako... recimo imam ovakav nekakav upit

Kod:
SELECT nesto
FROM tabela t1
INNER/LEFT JOIN x20
WHERE prost_uslov
AND (
	EXISTS (
		SELECT 1 FROM tabela t2
		INNER JOIN x5
		WHERE t1.id = t2.id
		AND jos_uslova
	)
	OR prost_uslov_2
)

i taj upit se izvršava 20+ sekundi za tabelu koja ima ~45k recorda.

Međutim, ako upit preformulišem kao
Kod:
SELECT tx.nesto
FROM (
	SELECT nesto
	FROM tabela
	INNER/LEFT JOIN x20
	WHERE prost_uslov
) tx
INNER JOIN tabela t1
WHERE EXISTS (
	SELECT 1 FROM tabela t2
	INNER JOIN x5
	WHERE t1.id = t2.id
	AND jos_uslova
)
OR prost_uslov_2
isti rezultat dobijem za 2-3 sekunde

Jedino objašnjenje koje imam je da se u prvom slucaju EXISTS primenjuje na svaki od 45k recorda, bez obriza da li bi ga prost_uslov isekao, dok u drugom ja garantujem da će se primeniti samo na one koji su prošli prost_uslov.

Zar je moguće da SQL Server optimizer nije u stanju da uradi ovaku jednostavnu optimizaciju, ili to treba negde ručno da se uključi?

Edit... Zaboravih, u pitanju je SQL Server 2000.
 
Poslednja izmena:
Nisam strucnjak za MS SQL server 2000, ali zar ne mozes da pogledas lepo plan optimizera za oba upita, tacno ces znati sta je uradio i koje je munje izbacio :d

Moguce je i da rearanzira nesto po upitu u zavisnosti od toga kako su napravljeni index-i.

Nisam puno pomogao, ali me bash interesuje objasnjenje :)
 
ali ali ali ti u oba slučaja praviš full Dekartov proizvod, zar ne?
na osnovu kog polja join-uješ te dve tabele

...
FROM
t1 LEFT JOIN t2 ON t1.field1 = t2.field2

ili bar da u WHERE uslov staviš
t1.field1 = t2.field2

inače ide full Dekart proizvod, znači 45k redova x N broj redova u prvoj tabeli

u drugom slučaju iz Dekartovog proizvoda smanjuješ ono N jer prvo izvršiš prost uslov tako da se brže izvršava
 
Nisam strucnjak za MS SQL server 2000, ali zar ne mozes da pogledas lepo plan optimizera za oba upita, tacno ces znati sta je uradio i koje je munje izbacio :d

Moguce je i da rearanzira nesto po upitu u zavisnosti od toga kako su napravljeni index-i.

Nisam puno pomogao, ali me bash interesuje objasnjenje :)

Pokušao sam da zaključim nešto iz execution plana, ali zbog onolikog broja joinova, toliko je nepregledan da sam izgubio volju da se udubljujem u njega :)
 
ali ali ali ti u oba slučaja praviš full Dekartov proizvod, zar ne?
na osnovu kog polja join-uješ te dve tabele

...
FROM
t1 LEFT JOIN t2 ON t1.field1 = t2.field2

ili bar da u WHERE uslov staviš
t1.field1 = t2.field2

inače ide full Dekart proizvod, znači 45k redova x N broj redova u prvoj tabeli

u drugom slučaju iz Dekartovog proizvoda smanjuješ ono N jer prvo izvršiš prost uslov tako da se brže izvršava

Pa da, u oba slučaja je Dekartov proizvod (stim što nisu u pitanju dve tabele, već jedna koju joinujem samu na sebe, po PK). To mora tako (barem ja nisam uspeo da smislim bolje rešenje :angel:).

Ono što mene zanima je zašto SQL server nije skontao da u konstrukciji
WHERE prost_uslov AND mnogo_slozen_uslov
kada prost_uslov postane false, više nema potrebe da izvršava mnogo_slozen_uslov
pošto će ceo WHERE sigurno biti false.
 
verovatno SQL Server to drugačije rezonuje...
To nije if grananje da on treba od zavisnosti true/false da ide jednim ili drugim putem, tu je filtriranje row-ova. Znači on gleda da napravi presek (AND) dva skupa podataka, jedan skup podataka daje prost_uslov a drugi daje mnogo_slozen_uslov.

verovatno ne radi "lenjo izracunavanje" da skonta ako je jedan skup prazan da ne racuna dalje?
 
Vrh Dno