PHP - MySQL - Foreach循环瓶颈

时间:2016-04-29 02:46:58

标签: php mysql

我有工作代码,但我似乎已经为我的代码引入了一个坏瓶颈。在详细介绍之前,让我先介绍一下这段代码的作用。我有一个用PHP / HTML生成的表,它显示了数据库中的部件列表(149个部分)。用户可以选择该项目的数量,然后单击“添加到购物车”,这一切都正常。

然而,我尝试通过添加一项功能来稍微改善一下,该功能只允许用户选择我们实际拥有的产品数量(在添加此功能之前,我之前将最大值硬编码为100) )。

现在这确实有效,但它很慢(加载页面50秒)。但是,在实现此页面之前,页面立即加载没有问题,因此这绝对是getPartQuantityOnHand()函数的问题。

我认为问题在于,对于每个部分(149),我调用此函数然后必须重新连接到数据库以找到正确的数量。有没有人看到我可以改进的方法?仅供参考,这些部件托管在一个完全独立的数据库上,托管这些部件的现有数量。

我已经从PHP代码中留下了一些部分,因为这篇帖子不必大量,我知道我在这里缺少部分。

getParts.php

        <?php
          $partList = $_SESSION['controller']->getParts();

          foreach ($partList as $part) {

            //Call to get the current quantity on hand for this specific part
            //THIS IS WHEN THE PROBLEM WAS INTRODUCED
            $quantityOnHand = $_SESSION['controller']->getPartQuantityOnHand($part->number);

            //Only display this part if we have at least one on hand
            if ($quantityOnHand > 0)
            {
              echo "<tr>";
                echo "<td>" . $part->number . "</td>";
                echo "<td>" . $part->description . "</td>";
                echo "<td>&#36;" . $part->price . "</td>";
                echo "<td>";
                   echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>';
                echo "</td>";
                  echo "</form>";
                echo "</td>";

              echo "</tr>";
            }
          }

          echo "</table>";
      echo "</div>";
    ?>

getPartQuantityOnHand()

    public function getPartQuantityOnHand($partNum) {
        $conn = $this->connect();

        $sql = "select Quantity from ReceivingInfo where PartNumber = '$partNum'";
        $stmt = $conn->prepare($sql);
        $stmt->execute();

        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        $quantityOnHand = $row['Quantity'];

        return $quantityOnHand;
    }

感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:1)

由于两个数据库是分开的,因此您有两个选择:

  1. 在循环并生成HTML之前确定部件号,然后使用IN子句同时查询所有部件:

    SELECT ... WHERE PartNumber IN (1, 2, 3, 4);
    
  2. 首次致电getPartQuantityOnHand时,选择所有零件的库存水平并存储:

    public function getPartQuantityOnHand($partNum) {
        if(!$this->partQuantitiesOnHand) {
            $conn = $this->connect();
    
            $sql = "select Quantity, PartNumber from ReceivingInfo";
            $stmt = $conn->prepare($sql);
            $stmt->execute();
    
            $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
            $this->partQuantitiesOnHand = array_column($rows, 'Quantity', 'PartNumber');
        }
    
        return $this->partQuantitiesOnHand[$partNum] ?? null;
    }
    
  3. 选项2的缺点是,如果您有比单个页面上列出的更多的部件,它将永远不会像选项1那样运行。

答案 1 :(得分:0)

因此,不要执行149个不同的SQL查询,只需执行一个查询即可返回所需的所有Quantity值。

离。

SELECT Quantity FROM ReceivingInfo WHERE PartNumber IN ($listOfPartNums)

当然你必须建立字符串$listOfPartNums

或者,如果您确实总是带回完整列表,则可以排除IN条款,而不必担心生成字符串。

您必须稍微更改一下您的功能,才能将partnum / quantity对存储在关联数组中。

然后在你的getParts.php中获取这样的数量:

  <?php
      $partList = $_SESSION['controller']->getParts();
      $quantityList = getQtyList(); // return assoc array of partnum/qty pairs

      foreach ($partList as $part) {

        //Call to get the current quantity on hand for this specific part
        //THIS IS WHEN THE PROBLEM WAS INTRODUCED
        $quantityOnHand = $quantityList[$part->number];

        //Only display this part if we have at least one on hand
        if ($quantityOnHand > 0)
        {
          echo "<tr>";
            echo "<td>" . $part->number . "</td>";
            echo "<td>" . $part->description . "</td>";
            echo "<td>&#36;" . $part->price . "</td>";
            echo "<td>";
               echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>';
            echo "</td>";
              echo "</form>";
            echo "</td>";

          echo "</tr>";
        }
      }

      echo "</table>";
  echo "</div>";
?>