Есть ли лучший цикл, который я мог бы написать, чтобы уменьшить количество запросов к базе данных? - PullRequest
3 голосов
/ 31 марта 2010

Ниже приведен код, который я написал, который эффективен, но выполняет слишком много запросов к базе данных. Есть ли способ, которым я мог бы оптимизировать и уменьшить количество запросов, но условия по-прежнему эффективны, как показано ниже?

Я вставил код, повторенный несколько раз просто для хорошей меры.

echo "<h3>Pool Packages</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

            if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Pool Packages") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
            }
            else { 
                $newprice = $query->price;                  
                $totals[] = $newprice; 
            }

            if ($query->category == "Pool Packages") {                          
                echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";         
            }

            else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Water Features</h3>"; 

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

            if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Water Features") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
            }
            else { 
                $newprice = $query->price;                  
                $totals[] = $newprice; 
            }

            if ($query->category == "Water Features") {         
                echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
            }
            else { }



    endforeach;

    echo "</ul>";

    echo "<h3>Waterfall Rock Work</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

            if ($item['quantity'] > 1 && $item['quantity'] == TRUE) {
                    $newprice = $item['quantity'] * $query->price;                                  
                    $totals[] = $newprice;  
            }
            else { 
                $newprice = $query->price;                  
                $totals[] = $newprice; 
            }

            if ($query->category == "Waterfall Rock Work") {            

                echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
            }

            else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Sheer Descents</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

        if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Sheer Descents") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
        }
        else { 
            $newprice = $query->price;                  
            $totals[] = $newprice; 
        }

        if ($query->category == "Sheer Descents") {         

            echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
        }

        else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Booster Pump</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

        if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Booster Pump") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
        }
        else { 
            $newprice = $query->price;                  
            $totals[] = $newprice; 
        }       

        if ($query->category == "Booster Pump") {

            echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
        }

        else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Pool Concrete Decking</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

        if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Pool Concrete Decking") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
        }
        else { 
            $newprice = $query->price;                  
            $totals[] = $newprice; 
        }           

        if ($query->category == "Pool Concrete Decking") {

            echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
        }

        else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Solar Heating</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

        if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Solar Heating") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
        }
        else { 
            $newprice = $query->price;                  
            $totals[] = $newprice; 
        }   

        if ($query->category == "Solar Heating") {

            echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
        }

        else { }

    endforeach;

    echo "</ul>";

    echo "<h3>Raised Bond Beam</h3>";

    echo "<ul>";

    foreach ($items as $item):  

        $this->db->where('id', $item['id']);
        $query = $this->db->get('items')->row();

        if ($item['quantity'] > 1 && $item['quantity'] == TRUE && $query->category == "Raised Bond Beam") {
                $newprice = $item['quantity'] * $query->price;                                  
                $totals[] = $newprice;  
        }
        else { 
            $newprice = $query->price;                  
            $totals[] = $newprice; 
        }

        if ($query->category == "Raised Bond Beam") {
            echo "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>";
        }

        else { echo "<li>None</li>"; }

    endforeach;

    echo "</ul>";

Это выходит за рамки этого еще для нескольких категорий, но я не знаю, как справиться с циклом через это лучше всего. Спасибо!

Ответы [ 4 ]

1 голос
/ 31 марта 2010

Вы можете создать HTML-код в переменной, чтобы выполнять цикл только один раз. Вот быстрый и грязный пример, чтобы показать вам, о чем я говорю:

$html = '';
$oldCat = '';
foreach ($items as $item) {  

    $this->db->where('id', $item['id']);
    $query = $this->db->get('items')->row();

    if ($oldCat != $query->category) {
        $html .= "</ul>\n";
        $html .= "<h3>".$query->category."</h3>\n<ul>\n";
        $oldCat = $query->category;
    }

    if ($item['quantity'] > 0) {
        $newprice = $item['quantity'] * $query->price;                                  
        $totals[] = $newprice;  
    }

    $html .= "<li>" . $query->name . " (QTY: " . $item['quantity'] . " x = " . str_ireplace(" ", "", money_format('%(#10n', $newprice)) . ")</li>\n";         

}
// strip leading /ul, append a /ul, echo html
0 голосов
/ 31 марта 2010

Вы должны использовать объединение элементов в категорию и получить все элементы, затем вы можете отсортировать их в многомерный массив и затем выполнить цикл для вывода.

Я не уверен, чем занимается ваше соединение классов db, но давайте предположим, что нам нужны все элементы этой категории:

$sql = "SELECT item.*, category.name as category from item, category WHERE item.category_id = category.item_id";

// ill use PDO for db access here...
$db = new PDO($connString, $username, $password);
$items = array(); // our array indexed by category.

foreach($db->query($sql) as $item) {
  if(!array_key_exists($items, $item['category']) {
     $items[$item['category']] = array();
  }

  $items[$item['category']][] = $item;
}

// now loop through $items using the similar stuff you did for output previously.
// note instead of doing the conditionals for pricing and stuff here you may want to
// do that in the loop above and put it in the array before hand... it will keep the
// output loop cleaner.
0 голосов
/ 31 марта 2010

Вы должны начать думать в терминах наборов, а не циклов. Напишите хранимый процесс, который принимает массив в качестве varchar (или в SQL Server 2008 вы можете использовать входной параметр с табличным значением, о других БД не знать).

Затем разбейте строку на временную таблицу и верните все записи в одном выбранном соединении с временной таблицей. Даже если вам нужно возвращать отдельные наборы записей, выполнение этого в хранимой процедуре уменьшит сетевой трафик.

0 голосов
/ 31 марта 2010

Вы можете сохранить все строки в отдельном массиве во время первого цикла, а затем ссылаться на массив во всех остальных циклах, вместо того, чтобы извлекать одну и ту же информацию снова и снова, предполагая, что вы выбрали *, который вы, вероятно, и есть.

Или, если не так много элементов больше, чем те, которые вы выбираете, вы можете использовать один запрос для выборки всех строк одновременно (вы используете только один запрос) и выполнить цикл для сохранения всех Значения в массиве $array[$row['id']] = $row (или что-то подобное) затем просто ссылаются на все эти строки в массиве в каждом из ваших циклов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...