Kodulehed
[386] - Andmebaasid I (ITI0206) (kevad 2024)
Esiletöstetud Kiirvalik
Lisainfo Kõige olulisemate tegevuste kiirvalik. Failide saatmiseks valige Vastamine alt sobiv ülesanne.
Üldist
Materjalid
LisainfoMaterjalide kataloogid
Isiklik
Lisainfo Info ainult Sulle - teised kasutajad seda ei näe
Abi
Lisainfo Võimalus küsida õppejõult abi (nagu foorum, kus saab küsida küsimusi ja kommenteerida vastuseid)
Mitmesugust
Abi / Kasutajatugi / SQL

Avalikud küsimused ja vastused:

Küsimuste teemade nimekiri

Anonüümne (21.04.2024 09:24):
Kas saate tuua näite sellest, kuidas ebaotstarbekas SQL ülesande lahendus mõjutab vastuse saamise kiirust?
Vastus (21.04.2024 09:38): Olgu meil PostgreSQL andmebaas järgmise kontseptuaalse struktuuriga:

[Facility]-1---------------0...*-[Health_care_visit]
 
Facility - 50_000 rida
Health_care_visit - 1_000_000 rida.

Järgnevad katsetused on tehtud PostgreSQL (16) põhjal. Täitmisplaanide ja täitmise kiiruse vaatamiseks kasutasin EXPLAIN ANALYZE lauset. Rõhutan, et nende ülesannete juures pakutud lahendusvariandid on loogiliselt samaväärsed e annavad alati sama tulemuse. 

Ülesanne - leia iga patsiendi kohta, kui mitmes protsendis erinevates tervishoiuasutustest on ta teinud vähemalt ühe külastuse. Ümarda tulemus ühe kohani peale koma.
 
Kirjutasin kaks lauset, et seda ülesannet lahendada. Lausetest on puudu nulliga jagamise vältimine, aga see ei muuda üldpilti.
 
Lause 1 - Tekitatakse tabelite Health_care_visit ja ja Facility otsekorrutis (leitakse kõikvõimalikud ridade paarid). Kasutatakse Count(DISTINCT ...), et leida tulemuse põhjal erinevate tervishoiuasutuste arv ja erinevate tervishoiuasutuste arv, kus on tehtud vähemalt üks reserveerimine.
 
SELECT hcv.patient_id, Round(Count(DISTINCT hcv.facility_id)::numeric/Count(DISTINCT facility.facility_id)*100,1) AS percentage
FROM Health_care_visit AS hcv, Facility
GROUP BY hcv.patient_id
ORDER BY hcv.patient_id;
 
Lause 2 - Kasutatakse Count(DISTINCT ...), et leida erinevate tervishoiuasutuste arv, kus on tehtud vähemalt üks reserveerimine. Tervishoiuasutuste arv leitakse eraldi alampäringuga.
 
SELECT hcv.patient_id, Round(Count(DISTINCT hcv.facility_id)::numeric/(SELECT Count(*) AS cnt FROM Facility)*100,1) AS percentage
FROM Health_care_visit AS hcv
GROUP BY hcv.patient_id
ORDER BY hcv.patient_id;
 
Lause 1 täitmiseks kulus 290 minutit ja lause 2 täitmiseks 370 millisekundit.
 
Lause 1 täitmise plaanist (lisatud pildina siia küsimusele) on näha, et tsüklis moodustatakse tulemus, kus on 50_000_000_000 (50 miljardit) rida ja siis asutakse korduseid eemaldama. Tsükli käigus materialiseeritakse e salvestatakse eraldi koopiana miljon korda tabeli Facility läbikäimise tulemus.

vaata ka faile:
Otsekorrutist kasutava SQL lause täitmisplaan[175 KB]

Hinda vastust:

Keskmine hinne : Pole veel hinnanguid!