2012-11-30 14 views
6

Powiedziano mi, że nieprawidłową praktyką jest użycie zapytania (select) w pętli, ponieważ spowalnia to działanie serwera.PHP Alternatywa dla użycia zapytania w pętli

mam szereg takich jak

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

Są to tylko trzy wskaźniki. Tablica, której używam, nie ma stałego rozmiaru, więc czasami może zawierać nawet 20 indeksów.

Teraz, co robię jest (to nie jest cały kod, ale podstawowa idea)

  1. Dla pętli
  2. zapytanie serwer i wybierz imiona wszystkich ludzi, którzy żyją w " Los Angeles”
  3. Print nazwy odchodzący

wyjście będzie wyglądać następująco:

Los Angeles 
     Michael Stern 
     David Bloomer 
     William Rod 

New York 
     Kary Mills 

Chicago 
     Henry Davidson 
     Ellie Spears 

Wiem, że to naprawdę nieskuteczna metoda, ponieważ może to być dużo zapytań, ponieważ tabela staje się później większa.

Moje pytanie brzmi: czy istnieje lepszy, skuteczniejszy sposób WYBIERANIA informacji w oparciu o elementy wewnątrz tablicy, które mogą mieć dowolny rozmiar?

+0

możesz użyć przygotówki http: //fr2.php.net/manual/pl/pdo.prepare.php – Ajouve

+0

Ludzie, 8 nieakceptowanych odpowiedzi jest całkowicie w porządku. OP już wie (jak to zrobił 5 razy), jak przyjąć odpowiedź. Bardzo możliwe, że nie otrzymał wystarczającej odpowiedzi na swoje pozostałe pytania. Daj mu odpocząć, proszę. –

+0

Dzięki za obronę mnie Madara, jesteś taka miła: ...) – r1nzler

Odpowiedz

4

aby dodatkowo dodać do MrCodes odpowiedź, jeśli zaczniesz z tablicą: -

$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 />"; 
    } 
} 

jako bazy a D poważny problem, prawdopodobnie powinieneś mieć nazwy miast w osobnej tabeli, a tabela dla osoby zawiera identyfikator miasta, a nie rzeczywistą nazwę miasta (ułatwia walidację, przyspiesza i przy walidacji jest mniej prawdopodobne, że nie trafi na rekordy, ponieważ ktoś ma źle wpisane ich rodzinne miasto)

+0

Stary ... jesteś bombą ... lol – r1nzler

0

Taki jest cel przygotowanych oświadczeń. Wiążesz element zastępczy z wartością i używasz go jak zmiennej z tym samym zapytaniem. Ponieważ zapytanie się nie zmieniło, minimalizujesz komunikację z serwerem mysql, co powoduje zwiększenie wydajności.

Przykład użyciu 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

Więc mówisz, że metoda, którą zrobiłem w moim poście jest w porządku? – r1nzler

4

Użyj IN zapytania, który weźmie wszystkich wyników w jednym zapytania:

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

A w jaki sposób wyniki są wyświetlane w pożądany sposób? Ta odpowiedź zupełnie nie odpowiada na pytanie zadawane przez PO. – eggyal

+1

@eggyal prawdziwe pytanie brzmi: jak poprawić efektywność powtarzanych zapytań, na które odpowiedziałem. OP nigdy właściwie nie pytał, jak wyprowadzać go w ten sposób. Jeśli OP ma specyficzne problemy z wyjściem, chętnie pomogę. – MrCode

1

jako @MrCode mentions można wykorzystać MySQL IN() operatorowi pobierania Rekordy dla wszystkich pożądanych miast za jednym razem, ale jeśli następnie uzyskasz sort swoje wyniki głównie według miasta, możesz przelecieć przez zestaw wyników, śledząc ostatnie miasto i wyświetlając nowe miasto, kiedy jest ono pierwsze ntered.

Korzystanie PDO wraz z FIELD() funkcji MySQL, aby upewnić się, że wynikowa jest w takiej samej kolejności jak oryginalnej tablicy (jeśli nie obchodzi, że można po prostu zrobić ORDER BY city, co byłoby dużo bardziej wydajne, zwłaszcza za pomocą odpowiedniego indeksu na kolumnie city):

$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

Dzięki stary, to bardzo pomogło! : D – r1nzler