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.