Kas saate tuua näite sellest, kuidas ebaotstarbekas SQL ülesande lahendus mõjutab vastuse saamise kiirust?

Postitas Erki Eessaar 21.04.2024 09:30 (muudeti 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.

Otsekorrutist kasutava SQL lause täitmisplaan

Otsekorrutist

Hinda postitust:

Keskmine hinne : Pole veel hinnanguid!