Datenbanabfragen reduzieren


Dragosius

Erfahrenes Mitglied
Hallo zusammen,

leider ist die Geschwindigkeit meiner Webseite nicht mehr so berauschend.
Mir ist auch mittlerweile bewusst, dass dies vermutlich an zu vielen SQL-Abfragen liegt.

Exemplarisch habe ich mal folgenden Teil raus gesucht:
Code:
    // Anzahl der Tauschanfragen
    $tauschAnfragenAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `partner_id` = $userId;"))['anzahl'];
   
    // Anzahl der Tauschangebote
    $tauschAngeboteAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `user_id` = $userId;"))['anzahl'];
   
    // Anzahl der Tauschannahmen
    $tauschAnnahmenAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tradescompleted` WHERE `partner_id` = $userId AND `accepted` LIKE '1'"))['anzahl'];
   
    // Anzahl der Tauschablehnungen
    $tauschAblehnungenAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tradescompleted` WHERE `partner_id` = $userId AND (`accepted` LIKE '0' OR `fail` LIKE '1')"))['anzahl'];
   
    // Gesamtanzahl der Tauschaktionen
    $tauschSummeAnzahl = $tauschAnfragenAnzahl + $tauschAnnahmenAnzahl + $tauschAblehnungenAnzahl + $wunschlistenUngelesen;
Hier kommt jeweils ein Ganzzahl raus, die ich später abfrage bzw ausgebe.

Wie kann ich denn sowas optimieren, so dass ich hier nicht mehr so viele einzelne Abfragen benötige?


Vielen Dank
 

Yaslaw

n/a
Moderator
So auf die Schnelle, du kannst auf 2 Abfragen reduzieren. Aber ob dass dan langsamer ist.
Aber Setze jeweils ein Index auf die tauschangebote.partner_id und einen auf tauschangebote.user_id

Bei der Tabelle tradescompleted
Ist da accepted wirklich als CHAR oder VARCHAR definiert? Scheint eher eine kleine Zahl zu sein. Dann sollte es auch so definiert sein und beim WHERE sicher nicht mit LIKE sondern mit = und ohne ''
SQL:
 AND `accepted` = 1
Was soll dieser Teil (`accepted` LIKE '0' OR `fail` LIKE '1')?
Der Text 'file' ist niemals gleich wie '1'. Somit ist der 2te Teil immer False und es kommt nur auf den Ersten drauf an
SQL:
-- Dein Code
AND (`accepted` LIKE '0' OR `fail` LIKE '1')
-- ist gleich wie
AND ( (`accepted` LIKE '0')   OR   (`fail` LIKE '1')  )
AND ( (`accepted` = 0)   OR   FALSE  )
-- und FALSE in einem OR wird nicht berücksichtig, ergo
AND `accepted` = 0
 

Dragosius

Erfahrenes Mitglied
Danke für die Rückmeldung.
Die Index hatte ich sogar schon gesetzt.
Das mit dem LIKE war wirklich unnötig, da beides nur ganze Zahlen sind.
`fail` ist auch eine Spalte, aber hier reicht ebenfalls =.
 

Dragosius

Erfahrenes Mitglied
Ich habe jetzt selbst noch etwas optimiert.

Was ist denn hier die bessere Wahl?

Version 1:
Code:
$tauschAnfragenAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `partner_id` = $userId;"))['anzahl'];
$tauschAngeboteAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `user_id` = $userId;"))['anzahl'];
Version 2:
Code:
$tauschangeboteZusammenfassung = sqlQuery("SELECT `user_id`, `partner_id` FROM `tauschangebote`;");

$tauschAnfragenAnzahl = 0;
$tauschAngeboteAnzahl = 0;
foreach($tauschangeboteZusammenfassung as $t) {
    if($t['partner_id'] == $userId) {
        $tauschAnfragenAnzahl++;
    } else if($t['user_id'] == $userId) {
        $tauschAngeboteAnzahl++;
    }
}
In Version 2 spare ich mir eine SQL-Abfrage ein, habe aber dafür die Schleife.
 

EuroCent

Erfahrenes Mitglied
Ich habe jetzt selbst noch etwas optimiert.

Was ist denn hier die bessere Wahl?

Version 1:
Code:
$tauschAnfragenAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `partner_id` = $userId;"))['anzahl'];
$tauschAngeboteAnzahl = mysqli_fetch_assoc(sqlQuery("SELECT COUNT(*) AS `anzahl` FROM `tauschangebote` WHERE `user_id` = $userId;"))['anzahl'];
Version 2:
Code:
$tauschangeboteZusammenfassung = sqlQuery("SELECT `user_id`, `partner_id` FROM `tauschangebote`;");

$tauschAnfragenAnzahl = 0;
$tauschAngeboteAnzahl = 0;
foreach($tauschangeboteZusammenfassung as $t) {
    if($t['partner_id'] == $userId) {
        $tauschAnfragenAnzahl++;
    } else if($t['user_id'] == $userId) {
        $tauschAngeboteAnzahl++;
    }
}
In Version 2 spare ich mir eine SQL-Abfrage ein, habe aber dafür die Schleife.
Deine Frage sollte sein, welche dann schneller und performanter ist :)

Ich denke aber das Variante 1 deutlich schneller und performanter ist.
 

Zvoni

Erfahrenes Mitglied
Eine weitere Möglichkeit wären noch SP's mit einem IN-Parameter und einem Rückgabewert (da du ja nur nen Count zurück haben willst) in Verbindung mit "Prepare"
Meinungen bzgl. Performance gehen da auseinander.


EDIT: Ein weiterer Optimierungs-Punkt könnte auch "COUNT(*)" vs "COUNT(ID)" sein
 
Zuletzt bearbeitet: