2012-11-30 23 views
6

Tôi đã được thông báo rằng việc sử dụng truy vấn (chọn) trong vòng lặp là một hành động không tốt vì nó làm chậm hiệu suất máy chủ.PHP Thay thế cho việc sử dụng truy vấn trong vòng lặp

Tôi có một mảng như

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

Đây chỉ là 3 chỉ số. Mảng tôi đang sử dụng không có kích thước cố định, vì vậy đôi khi nó có thể chứa tối đa 20 chỉ mục.

Ngay bây giờ, những gì tôi đang làm là (đây không phải là tất cả các mã, nhưng ý tưởng cơ bản)

  1. Đối với loop
  2. truy vấn các máy chủ và chọn tên tất cả của những người sống trong " Los Angeles"
  3. In tên ra

Output sẽ trông như thế này:

Los Angeles 
     Michael Stern 
     David Bloomer 
     William Rod 

New York 
     Kary Mills 

Chicago 
     Henry Davidson 
     Ellie Spears 

Tôi biết đó là một phương pháp thực sự không hiệu quả vì có thể có nhiều truy vấn vì bảng sẽ lớn hơn sau này.

Vì vậy, câu hỏi của tôi là, có cách nào tốt hơn, hiệu quả hơn để chọn thông tin dựa trên nội dung bên trong một mảng có thể là kích thước bất kỳ không?

+0

bạn có thể sử dụng http: //fr2.php chuẩn bị.net/manual/en/pdo.prepare.php – Ajouve

+0

Mọi người, 8 câu trả lời không được chấp nhận là hoàn toàn ổn. OP đã biết (Như anh ta đã làm nó 5 lần) làm thế nào để chấp nhận một câu trả lời. Rất có thể là anh ta không nhận được câu trả lời đầy đủ về các câu hỏi khác của mình. Hãy cho anh ta một break xin vui lòng. –

+0

Cảm ơn bạn đã bảo vệ tôi Madara, bạn thật tuyệt vời: ...) – r1nzler

Trả lời

4

tiếp tục thêm vào MrCodes câu trả lời, nếu bạn bắt đầu với một mảng: -

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

là một cơ sở dữ liệu d esign vấn đề, bạn có lẽ nên có tên thị trấn trong một bảng riêng biệt và bảng cho người có chứa id của thị trấn hơn là tên thị trấn thực tế (làm cho xác nhận dễ dàng hơn, nhanh hơn và với xác nhận ít có khả năng bỏ lỡ hồ sơ vì ai đó có mistyped town town của họ)

+0

Dude .. bạn là bom ... lol – r1nzler

0

Đó là mục đích của các câu được chuẩn bị. Bạn liên kết một trình giữ chỗ với một giá trị và sử dụng nó như một biến, với cùng một truy vấn. Kể từ khi truy vấn không thay đổi, bạn giảm thiểu giao tiếp với máy chủ mysql, dẫn đến tăng hiệu quả.

Ví dụ sử dụng 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

Vì vậy, bạn có nói phương pháp tôi đã thực hiện trong bài đăng của tôi không? – r1nzler

4

Sử dụng một truy vấn IN, mà sẽ lấy tất cả các kết quả trong một truy vấn duy nhất:

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

Và làm thế nào để một kết quả đầu ra trong thời trang mong muốn? Câu trả lời này hoàn toàn không giải quyết được câu hỏi mà OP đã hỏi. – eggyal

+1

@eggyal câu hỏi thực sự là làm thế nào để cải thiện hiệu quả của các truy vấn lặp đi lặp lại, mà tôi đã trả lời. OP không bao giờ thực sự hỏi làm thế nào để sản xuất nó theo cách đó. Nếu OP có vấn đề cụ thể với đầu ra sau đó tôi sẽ sẵn sàng giúp đỡ. – MrCode

1

Như @MrCode mentions, bạn có thể sử dụng toán tử IN() MySQL để lấy hồ sơ cho tất cả các thành phố mong muốn trong một lần, nhưng nếu bạn sau đó sort kết quả của bạn chủ yếu theo thành phố, bạn có thể lặp lại theo dõi kết quả của thành phố cuối cùng nhìn thấy và xuất ra thành phố mới khi nó là lần đầu tiên ntered.

Sử dụng PDO, cùng với chức năng FIELD() của MySQL để đảm bảo kết quả theo thứ tự như mảng ban đầu của bạn (nếu bạn không quan tâm, bạn chỉ cần thực hiện ORDER BY city, hiệu quả hơn rất nhiều, đặc biệt là với một chỉ số thích hợp vào cột 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

Cảm ơn dude, điều này thực sự đã giúp rất nhiều! : D – r1nzler

Các vấn đề liên quan