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 1Lause 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 2Lause 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.