MySQL: Abfrage aus einer Schleife nach außerhalb verschieben

Dragosius

Erfahrenes Mitglied
Hallo zusammen,

momentan habe ich folgende Schleife bei mir in Verwendung:

PHP:
while (list($key, $value) = each($arr)) {
    # echo "Key: $key; Value: $value<br>\n";
    $query = "SELECT * FROM posting WHERE po_id = " . intval($value);
 
    $result = mysqli_query($mysqli_link, $query);
    $num = mysqli_num_rows($result);
 
    if ($num == 0)
        $diff--;
}

Das Problem ist nur, dass dies den Aufbau der Seite extrem verlangsamt, weil diese Schleife sehr oft durchlaufen werden muss.

Aus dem Grund hatte ich die Idee die SQL-Abfrage einmal über die komplette Tabelle außerhalb der Schleife durchzuführen:
PHP:
    $query = "SELECT * FROM posting";
    $result = mysqli_query($mysqli_link, $query);

Dazu hätte ich nun jedoch 2 Fragen:
1. Ist meine Annahme korrekt, dass dies wesentlich performanter ist?
2. Wie kann ich in der Schleife dann über die korrekten Werte aus der Datenbank filtern (also nach $value) ?


Vielen Dank
 

Zvoni

Erfahrenes Mitglied
1) Gewöhne dir das "SELECT * FROM" ab. Hol dir nur Spalten, die du auch wirklich brauchst. Hat unter Umständen auch merkbare Auswirkungen auf Performance
2) ich hab von PHP keine Ahnung, bin mir aber sicher, dass MySQL den "IN"-Operator unterstützt.
Versuch in einer Schleife vorher einen String zusammen zu bauen, welchen du dann an dein SELECT-Statement hängst
Aircode
SQL:
SELECT Spalte1, Spalte2, Spalte3 usw.
FROM posting
WHERE
po_id IN (1,2,3,4,8,10,12,27)
und das in der Klammer "(1,2,3...." müsstest du in der Schleife zusammenbauen, oder du hast es bereits in einem array. Dann per implode
PHP: implode - Manual
 

Dragosius

Erfahrenes Mitglied
Danke dir, ich habe es nun so gelöst:

PHP:
    // Alle Themen der Variable zuordnen
    $themen = '';
    while (list($key, $value) = each($arr)) {
        $themen .= intval($value) . ',';
    }
    // Wenn keine Themen vorhanden sind, auf 0 setzen, ansonsten das letzte Komma entfernen
    if($themen == '') {
        $themen = 0;
    } else {
        $themen = substr($themen, 0, -1);
    }
    $query = "SELECT po_id FROM posting WHERE po_id IN (".$themen.") ";
    
    $result = mysqli_query($mysqli_link, $query);
    $num = mysqli_num_rows($result);

Der Seitenaufbau ist dadurch nun auch um ein vielfaches schneller.
 

Yaslaw

alter Rempler
Moderator
Du hast doch $arr als Array mit den Themen-IDs. Warum so kompliziert den String zusammensetzen? Dazu gibt es ganz einfache PHP-Befehle
PHP:
$arr = array(1,2,14,'55');  //Test-Array
$themen = count($arr) == 0 ? '0' : implode(',', $arr);
Wenn du umsverrecken den intval auf jedes Element anwenden willst, dann verwnede array_walk() oder array_map()
PHP:
$themen = count($arr) == 0 ? 0 : implode(',', array_map('intval', $arr));
Also anstelle von 9 Zeilen nur eine Zeile.
 

Zvoni

Erfahrenes Mitglied
Sein SQL in Zeile 12 ergibt für mich keinen Sinn.

SELECT po_id FROM posting WHERE po_id IN….
Wieso nur po_id selecten welche eh vorgefiltert werden aus dem array?
ist die Abfrage überhaupt notwendig?

EDIT: oder hat das array mit den po_id nichts zu tun?
Einziger Sinn wäre, z.B. 10 id aus dem Array zu übergeben, aber nur 8 tatsächlich zurück zu bekommen, weil 2 nicht in der db existieren

ausserdem hab ich implode explizit auch erwähnt. Verstehe das Schleifen-Gehampel auch nicht