繁体   English   中英

PHP-MySQL-Foreach循环瓶颈

[英]PHP - MySQL - Foreach loop bottleneck

我有可用的代码,但似乎对我的代码引入了严重的瓶颈。 在详细介绍之前,让我给您一些有关此代码作用的背景知识。 我有一个用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;
    }

感谢您的任何帮助,您可以提供!

因此,与其执行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>";
?>

由于两个数据库是分开的,所以有两个选择:

  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; } 

选项2的缺点是,如果部件的数量比单个页面上列出的数量多,它的性能将永远不会比选项1好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM