有没有更好的循环我可以编写以减少数据库查询?

时间:2010-03-31 18:32:15

标签: php loops

下面是我编写的一些有效的代码,但是会产生太多的数据库查询。有没有一种方法可以优化和减少查询数量,但条件语句仍然有效,如下所示?

为了更好的衡量标准,我重复粘贴了几次代码。

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 个答案:

答案 0 :(得分:1)

您可以在变量中构建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

答案 1 :(得分:0)

你可以在第一个循环中将所有行存储到一个单独的数组中,然后在所有其他循环中引用数组,而不是一遍又一遍地获取相同的信息,假设你选择*你可能是。

或者,如果项目的数量多于您要提取的项目,则可以使用单个查询一次获取所有行(您只使用一个查询)并循环显示所有项目以存储所有项目数组$array[$row['id']] = $row中的值(或类似的东西)然后只是引用每个循环中数组中的所有行。

答案 2 :(得分:0)

你应该使用从项目到类别的连接并获取所有项目,然后你可以将它们排序成一个多维数组,然后遍历它以进行输出。

我不确定你的类连接是做什么的,但我们假设我们想要所有类别的项目:

$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.

答案 3 :(得分:0)

你需要开始考虑集合而不是循环。编写一个存储过程,将数组作为varchar(或者在SQL Server 2008中,您可以使用表值输入参数,不知道其他dbs)。

然后将字符串拆分为临时表,并返回一个选择的所有记录,并加入临时表。即使您需要返回单独的记录集,在存储过程中执行此操作也会减少网络流量。