Kodulehed
[388] - Andmebaasid I (ITI0206) (kevad 2025)
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 (06.03.2025 16:39):
Kuidas leida iga rea kohta ühest tabelist selliste ridade arv teisest tabelist, mis rahuldavad mingit tingimust? Kas erinevatel lahendustel on töökiiruse mõttes erinevusi?
Vastus (06.03.2025 16:52):
Toon näite. Olgu meil PostgreSQL andmebaas, millel on järgmine kontseptuaalne struktuur

[Facility]-1-------------0..*-[Health_care_visit]

Tabelis Facility on 50_000 rida.
Tabelis Health_care_visit on 1_000_000 rida.

Järgnevad katsetused on tehtud PostgreSQL (17) 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. Kõik need on kokku näide "abstraktsioonide lekkimise" kohta e selle kohta, kuidas andmete füüsilise ("süsteemi kaane all") salvestamise ja töötlemise küsimused "lekivad" andmete kasutaja maailma ja kokkuvõttes peab ta teadma, kuidas oleks konkreetses süsteemis kõige otstarbekam oma küsimusi formuleerida.

Ülesanne: Leia iga rea kohta tabelis Facility selliste ridade arv tabelis Health_care_visit, kus külastus algas 2010. aastal.

Kõikides lahendustes kasutatakse välisühendamist, et tulemuses oleksid ka sellised read tabelist Facility, millele ei ole tingimusele vastavaid ridu tabelis Health_care_visit.

Lahendus 1:
SELECT facility_name, Count(hcv.facility_id) AS cnt
FROM Facility LEFT JOIN health_care_visit AS hcv ON Facility.facility_id=hcv.facility_id
AND Extract(year FROM from_date)=2010
GROUP BY facility_name;

Teises tabelis huvipakkuvaid ridu piirav tingimus on kirjutatud ühendamise tingimusse.

Lahendus 2:
WITH hcv AS (SELECT facility_id
FROM health_care_visit 
WHERE Extract(year FROM from_date)=2010)
SELECT facility_name, Count(hcv.facility_id) AS cnt
FROM Facility LEFT JOIN hcv ON Facility.facility_id=hcv.facility_id
GROUP BY facility_name;

Teises tabelis huvipakkuvad read leitakse alampäringuga, mis on vormistatud ühise tabeli avaldisena. Põhipäringus ühendatakse need andmed esimese tabeliga ning arvutatakse koondandmed.

Lahendus 3:
SELECT facility_name, Count(hcv.facility_id) FILTER (WHERE Extract(year FROM from_date)=2010) AS cnt
FROM Facility LEFT JOIN health_care_visit AS hcv ON Facility.facility_id=hcv.facility_id
GROUP BY facility_name;

Kasutatakse FILTER funktsionaalsust.

Lahenduste 1 ja 2 korral kasutas andmebaasisüsteem tabeli Health_care_visit kõigi ridade läbivaatamiseks kahte paralleelprotsessi. Lause täitmine võttis umbes 150 ms.
Lahenduse 3 korral vaatas andmebaasisüsteem samuti läbi kõik tabeli Health_care_visit read, kuid paralleeltööd sealjuures ei kasutanud ning lause täitmine võttis umbes 500 ms.

Hinda vastust:

Keskmine hinne : Pole veel hinnanguid!