Kodulehed
[385] - Andmebaasid II (ITI0207) (sügis 2023)
Esiletöstetud Kiirvalik
Lisainfo Kõige olulisemate tegevuste kiirvalik. Failide saatmiseks valige Vastamine alt sobiv ülesanne.
Üldist
Materjalid
LisainfoMaterjalide kataloogid.
Värvilised mummud tähistavad hinnangulist kataloogide lugemise vajadust. Roheline - suurim, kollane - keskmine, punane või mummuta - väikseim
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 / Andmebaasisüsteemid (Üldine)

Avalikud küsimused ja vastused:

Küsimuste teemade nimekiri

Erki Eessaar (03.12.2022 13:53):
Juhul kui välisühendamist ei ole lause õige tulemuse saavutamiseks vaja, siis kas OUTER JOIN operatsiooni kasutamine INNER JOIN asemel mõjutab lause täitmisplaani valikut ja seega ka lause täitmise kiirust? (2)
Vastus (03.12.2022 15:19): Sõltub päringust ja andmebaasisüsteemist.

Katsetasin Oracles (12.1) ja PostgreSQL (14) põhjal, mis olid samas serverarvutis. Katsetamisel kasutatud andmebaas ja andmed olid ühesugused.

Vähemalt konkreetsete süsteemide ja katsetatud lausete puhul tingis just OUTER JOIN (välisühendamise) kasutamine tabeli elimineerimise teisenduse rakendamise andmebaasisüsteemi poolt (juhul kui see oli võimalik), mis andis tulemuseks parema töökiiruse. Tabeli elimineerimise teisenduse idee seisneb selles, et kui päringus viidata tabelile, mida pole lause täitmiseks vaja lugeda, siis kirjutab andmebaasisüsteem ise lause ümber nii, et seda tabelit ei kasutata.

Katsetes kasutatud laused olid loogiliselt samaväärsed, st INNER vs OUTER JOIN kasutamine ei muutnud tulemust.

Andmebaas:

[Party]-1----------0..1-[Person]-1--------0..*-[Health_care_visit]

Tabelis Party - 100 000 rida
Tabelis Person - 70 000 rida
Tabelis Health_care_visit - 1 miljon rida

Katse 1

Lause 1:
SELECT Count(*) AS cnt
FROM Health_care_visit LEFT JOIN Person ON Health_care_visit.patient_id=Person.party_id
LEFT JOIN Party USING (party_id);

Lause 2:
SELECT Count(*) AS cnt
FROM Health_care_visit INNER JOIN Person ON Health_care_visit.patient_id=Person.party_id
INNER JOIN Party USING (party_id);

PostgreSQL tulemus: (LEFT JOIN parem)
Täitmisplaanid erinevad.
Lause 1 täitmine 0.21 sekundit (tänu tabeli elimineerimise teisendusele loeti ainult tabelit Health_care_visit).
Lause 2 täitmine 0.76 sekundit (loeti tabelit Health_care_visit ja lisaks tabelite Person ja Party primaarvõtme indeksit).

Oracle tulemus: (LEFT JOIN parem)
Täitmisplaanid erinevad.
Lause 1 täitmine 0.07 sekundit (tänu tabeli elimineerimise teisendusele loeti ainult tabeli Health_care_visit primaarvõtme indeksit).
Lause 2 täitmine 0.34 sekundit (loeti tabelit Health_care_visit indeksit ja lisaks tabeli Party primaarvõtme indeksit).

Katse 2

Lause 1
SELECT Count(*) AS cnt
FROM Health_care_visit LEFT JOIN Person ON Health_care_visit.patient_id=Person.party_id
LEFT JOIN Party USING (party_id)
WHERE Health_care_visit.visit_fee>100;

Lause 2:
SELECT Count(*) AS cnt
FROM Health_care_visit INNER JOIN Person ON Health_care_visit.patient_id=Person.party_id
INNER JOIN Party USING (party_id)
WHERE Health_care_visit.visit_fee>100;

PostgreSQL tulemus: (LEFT JOIN parem)
Täitmisplaanid erinevad.
Lause 1 täitmine 0.3 sekundit (tänu tabeli elimineerimise teisendusele loeti ainult tabelit Health_care_visit).
Lause 2 täitmine 0.85 sekundit (loeti tabelit Health_care_visit ja lisaks tabelite Person ja Party primaarvõtme indeksit).

Oracle tulemus: (LEFT JOIN parem)
Täitmisplaanid erinevad.
Lause 1 täitmine 0.11 sekundit (tänu tabeli elimineerimise teisendusele loeti ainult tabelit Health_care_visit).
Lause 2 täitmine 0.75 sekundit (loeti tabelit Health_care_visit ja lisaks tabeli Party primaarvõtme indeksit).

Katse 3:

Lause 1:
SELECT Health_care_visit.patient_id, Health_care_visit.from_date, Health_care_visit.thru_date, Person.last_name, Person.height, Person.weight, Party.contact_number
FROM Health_care_visit LEFT JOIN Person ON Health_care_visit.patient_id=Person.party_id
LEFT JOIN Party USING (party_id);

Lause 2:
SELECT Health_care_visit.patient_id, Health_care_visit.from_date, Health_care_visit.thru_date, Person.last_name, Person.height, Person.weight, Party.contact_number
FROM Health_care_visit INNER JOIN Person ON Health_care_visit.patient_id=Person.party_id
INNER JOIN Party USING (party_id);

PostgreSQL tulemus (viik):
Täitmisplaanid veidi erinevad (tabelid ühendati samas järjekorras, kasutati hash joini).
Lause 1 täitmine 0.74 sekundit (loeti kõiki tabeleid).
Lause 2 täitmine 0.74 sekundit (loeti kõiki tabeleid).

Oracle tulemus: (INNER JOIN veidi parem)
Täitmisplaanid erinevad (tabelid ühendati erinevas järjekorras, kasutati hash joini).
Lause 1 täitmine 6.76 sekundit (loeti kõiki tabeleid).
Lause 2 täitmine 5.82 sekundit (loeti kõiki tabeleid).

Tabeli elimineerimise teisendust ei saa kasutada, sest päringus küsitatakse andmeid kõigist tabelitest.

Hinda vastust:

Keskmine hinne : Pole veel hinnanguid!