2012-11-30 13 views
6

Mir wurde gesagt, dass es eine schlechte Übung ist, eine Abfrage (select) innerhalb einer Schleife zu verwenden, weil sie die Serverleistung verlangsamt.PHP Alternative zur Verwendung einer Abfrage innerhalb einer Schleife

Ich habe ein Array wie

Array ([1] => Los Angeles) 
Array ([2] =>New York) 
Array ([3] => Chicago) 

Dies sind nur drei Indizes. Das Array, das ich verwende, hat keine konstante Größe, daher kann es manchmal bis zu 20 Indizes enthalten.

Gerade jetzt, was ich ist zu tun (das ist nicht der gesamte Code ist, aber die Grundidee)

  1. For-Schleife
  2. Abfrage der Server und wählen Sie alle Namen der Menschen, die in "leben Los Angeles“
  3. drucken die Namen aus

die Ausgabe wird wie folgt aussehen:

Los Angeles 
     Michael Stern 
     David Bloomer 
     William Rod 

New York 
     Kary Mills 

Chicago 
     Henry Davidson 
     Ellie Spears 

Ich weiß, dass das eine wirklich ineffiziente Methode ist, weil es viele Abfragen geben könnte, wenn die Tabelle später größer wird.

Also meine Frage ist, gibt es einen besseren, effizienteren Weg zum AUSWÄHLEN von Informationen basierend auf dem Zeug in einem Array, das jede Größe haben kann?

+0

können Sie eine Vorbereitung http: //fr2.php verwenden.net/manual/de/pdo.prepare.php – Ajouve

+0

Menschen, 8 nicht akzeptierte Antworten ist völlig in Ordnung. OP weiß bereits (wie er es 5 mal gemacht hat), wie man eine Antwort akzeptiert. Es ist sehr gut möglich, dass er auf seine anderen Fragen keine ausreichende Antwort bekommen hat. Gib ihm bitte eine Pause. –

+0

Danke für die Verteidigung Madara, du bist so nett: ...) – r1nzler

Antwort

4

um zu MrCodes Antwort hinzufügen weiter, wenn Sie mit einer Reihe starten: -

$Cities = array(1=>'Los Angeles', 2=>'New York', 3=>'Chicago'); 
$query = "SELECT town, personname FROM people WHERE town IN('".implode("','", $Cities)."') ORDER BY town"; 
if ($sql = $mysqliconnection->prepare($query)) 
{ 
    $sql->execute(); 
    $result = $sql->get_result(); 
    $PrevCity = ''; 
    while ($row = $result->fetch_assoc()) 
    { 
     if ($row['town'] != $PrevCity) 
     { 
      echo $row['town']."<br />"; 
      $PrevCity = $row['town']; 
     } 
     echo $row['personname']."<br />"; 
    } 
} 

Als Datenbank d Esign-Problem, sollten Sie wahrscheinlich die Stadt Namen in einer separaten Tabelle und die Tabelle für die Person enthält die ID der Stadt und nicht den tatsächlichen Namen der Stadt (macht Validierung einfacher, schneller und mit der Validierung weniger wahrscheinlich Datensätze zu verpassen, weil jemand hat vertippte ihre Heimatstadt)

+0

Alter ... du bist die Bombe ... lol – r1nzler

0

Das ist der Zweck der vorbereiteten Aussagen. Sie binden einen Platzhalter an einen Wert und verwenden ihn wie eine Variable mit derselben Abfrage. Da sich die Abfrage nicht geändert hat, minimieren Sie die Kommunikation mit dem MySQL-Server, was zu einer Effizienzsteigerung führt.

Beispiel mit PDO:

$cities = array(
    "Los Angeles", 
    "New York", 
    "Chicago" 
); 

try { 
    //Change database parameters here (user, pass, database name) 
    $db = new PDO("mysql:host=localhost;dbname=users", "user", "pass"); 
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

    $stmt = $db->prepare("SELECT * FROM `users` WHERE `city` = :city"); 

    foreach ($cities as $city) { 
     $stmt->bindValue(":city", $city); 
     $stmt->execute(); 

     $result = $stmt->fetchAll(PDO::FETCH_ASSOC); 
     //Output data here. You can format it however you'd like 
     var_dump($city, $result); 
    } 

} 
catch (PDOException $e) { 
    //Error handling here 
} 
+0

Also sagst du, dass die Methode, die ich in meinem Beitrag gemacht habe, in Ordnung ist? – r1nzler

4

Verwenden Sie eine IN Abfrage, die alle Ergebnisse in einer einzigen Abfrage greifen wird:

SELECT * FROM people WHERE town IN('LA', 'London', 'Paris') 
+0

Und wie gibt man dann die Ergebnisse in der gewünschten Weise aus? Mit dieser Antwort wird die vom OP gestellte Frage nicht vollständig beantwortet. – eggyal

+1

@eggyal die echte Frage ist, wie die Effizienz der wiederholten Abfragen zu verbessern, die ich beantwortet habe. OP hat nie gefragt, wie man es auf diese Weise ausgibt. Wenn OP spezifische Probleme mit der Ausgabe hat, würde ich gerne helfen. – MrCode

1

Als @MrCode mentions, können Sie MySQL verwenden IN() Operator zu holen Datensätze für alle gewünschten Städte auf einmal, aber wenn Sie dann sort Ihre Ergebnisse in erster Linie nach Stadt können Sie über die Ergebnismenge, die Spur der zuletzt gesehenen Stadt und die Ausgabe der neuen Stadt, wenn es zum ersten Mal ist ntered.

PDO Verwendung zusammen mit FIELD() Funktion von MySQL, um sicherzustellen, dass die Ergebnismenge in der gleichen Reihenfolge wie Ihre ursprüngliche Array ist (wenn Sie nicht über das kümmern, könnten Sie einfach tun ORDER BY city, die viel effizienter wären, insbesondere mit einem geeigneten Index für die city Spalte):

$arr = ['Los Angeles', 'New York', 'Chicago']; 
$placeholders = rtrim(str_repeat('?, ', count($arr)), ', '); 

$dbh = new PDO("mysql:dbname=$dbname", $username, $password); 
$qry = $dbh->prepare(" 
    SELECT city, name 
    FROM  my_table 
    WHERE city IN ($placeholders) 
    ORDER BY FIELD(city, $placeholders) 
"); 

if ($qry->execute(array_merge($arr, $arr))) { 

    // output headers 
    echo '<ul>'; 

    $row = $qry->fetch(); 
    while ($row) { 
    $current_city = $row['city']; 

    // output $current_city initialisation 
    echo '<li>'.htmlentities($current_city).'</li><ul>'; 
    do { 
     // output name $row 
     echo '<li>'.htmlentities($row['name']).'</li>'; 
    } while ($row = $qry->fetch() and $row['city'] == $current_city); 
    // output $current_city termination 
    echo '</ul>'; 
    } 

    // output footers 
    echo '</ul>'; 
} 
+0

Danke Kumpel, das hat wirklich sehr geholfen! : D – r1nzler

Verwandte Themen