Temat: Zadanie SQL, pomocy!!!!!!!!!!!!!
No to może ja podam trochę bardziej
"eleganckie" rozwiązanie - bez użycia podzapytań
SELECT
t1.data_rozpoczecia,
min(t2.data_rozpoczecia) as data_zakonczenia,
min(t2.data_rozpoczecia)-t1.data_rozpoczecia as dl_turnusu
FROM
turnusy t1 LEFT JOIN turnusy t2 ON (t1.data_rozpoczecia < t2.data_rozpoczecia)
GROUP BY
t1.data_rozpoczecia
ORDER BY
t1.data_rozpoczecia;
Dzięki brakowi podzapytań wykonuje się również kilkadziesiąt procent szybciej niż zaprezentowana wcześniej wersja rozwiązania.
Jeśli chcesz pozbyć się ostatniego wiersza w którym nie ma terminu zakończenia zamień
LEFT JOIN na
JOIN.
Analiza tego zapytania (PostgreSQL):
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=20.00..25079.51 rows=1000 width=8) (actual time=0.060..0.156 rows=8 loops=1)
-> Nested Loop Left Join (cost=20.00..22572.00 rows=333334 width=8) (actual time=0.028..0.130 rows=29 loops=1)
Join Filter: ("outer".data_rozpoczecia Index Scan using turnusy_pkey on turnusy t1 (cost=0.00..52.00 rows=1000 width=4) (actual time=0.015..0.023 rows=8 loops=1)
-> Materialize (cost=20.00..30.00 rows=1000 width=4) (actual time=0.001..0.004 rows=8 loops=8)
-> Seq Scan on turnusy t2 (cost=0.00..20.00 rows=1000 width=4) (actual time=0.002..0.006 rows=8 loops=1)
Total runtime: 0.211 ms
(7 rows)
Time: 1,437 ms
Analiza rozwiązania poprzedniego
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
Sort (cost=46831.57..46834.08 rows=1001 width=8) (actual time=0.516..0.517 rows=8 loops=1)
Sort Key: t.data_rozpoczecia
-> Hash Join (cost=22.50..46781.69 rows=1001 width=8) (actual time=0.331..0.502 rows=8 loops=1)
Hash Cond: ("outer".data_rozpoczecia = "inner".data_rozpoczecia)
-> Seq Scan on turnusy t (cost=0.00..20.00 rows=1000 width=4) (actual time=0.001..0.004 rows=8 loops=1)
-> Hash (cost=20.00..20.00 rows=1000 width=4) (actual time=0.025..0.025 rows=0 loops=1)
-> Seq Scan on turnusy t1 (cost=0.00..20.00 rows=1000 width=4) (actual time=0.007..0.011 rows=8 loops=1)
SubPlan
-> Aggregate (cost=23.34..23.34 rows=1 width=4) (actual time=0.009..0.009 rows=1 loops=8)
-> Seq Scan on turnusy t2 (cost=0.00..22.50 rows=334 width=4) (actual time=0.002..0.006 rows=4 loops=8)
Filter: (data_rozpoczecia > $0)
-> Aggregate (cost=23.34..23.34 rows=1 width=4) (actual time=0.010..0.010 rows=1 loops=8)
-> Seq Scan on turnusy t2 (cost=0.00..22.50 rows=334 width=4) (actual time=0.002..0.006 rows=4 loops=8)
Filter: (data_rozpoczecia > $0)
Total runtime: 0.611 ms
(15 rows)
Time: 2,167 ms
A więc wzrost skomplikowania zapytania a co za tym idzie także czasu wykonania - 2,167ms zamiast 1,437 ms a więc wzrost o ponad 50%. Dlatego "keep it simple" .
P.S Na co dzień mam do czynienia z bardzo dużymi bazami danych więc mam bzika na punkcie optymalizacji zapytań :)
Marcin M. edytował(a) ten post dnia 25.11.06 o godzinie 23:24