For循环正在进行3600个数据库请求以加载产品。 PHP

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了For循环正在进行3600个数据库请求以加载产品。 PHP相关的知识,希望对你有一定的参考价值。

问题:一件(我们当前可以识别)导致客户产品列表在加载更长的产品列表时一次又一次地(3600次)调用数据库。

码:

<?php foreach ($cats as $cat) :
if (in_array($cat->getId(), [68, 28, 27, 59, 79, 80, 119])) :

$cat_show = Mage::getModel('catalog/category')->load($cat->getId());
$children = $cat_show->getChildrenCategories($cat->getId());
$url1 = $cat_show->getURL();
$showAnyways = in_array(strtolower($cat_show->getName()), ["hats", "juniors", "accessories"]);

if ($cat_show->getShowSidebar() == 1 || $showAnyways) : ?>
<li class="current<?php if ($cat->getId() == $current_cat) { ?> active <?php } ?>">
    <a href="<?php echo $url1 ?>"><?php echo $cat->getName() ?></a>
    <ul>
        <?php if ($cat_show->getID() != 68 && $cat_show->getID() != 59) { ?>
            <li class="current<?php if ($cat->getId() == $current_cat && $j == 0) {
                $j++; ?> active<?php } ?>"><a class="view_all" href="<?php echo $url1 ?>"><?php echo $this->__("View All"); ?></a></li>
        <?php } ?>
        <?php foreach ($children as $subcat) {
            $subcat_show = Mage::getModel('catalog/category')->load($subcat->getId());
            if ($subcat_show->getShowSidebar() == 1 || in_array($subcat_show->getID(), [84])) {
                $grand_children = Mage::getModel('catalog/category')->getCategories($subcat->getId());
                if ($grand_children) {
                    $cats_displayed = 0;
                    foreach ($grand_children as $grand_child) {
                        $grand_child_show = Mage::getModel('catalog/category')->load($grand_child->getId());
                        if ($grand_child_show->getShowSidebar() == 1) {
                            $url = Mage::getModel('catalog/category')->load($grand_child_show->getId())->getURL();
                            ?>
                            <li class="current<?php if ($grand_child->getId() == $current_cat && $j == 0) {
                                $j++; ?> active<?php } ?>">
                                <a href="<?php echo $url ?>"><?php echo $grand_child_show->getName() ?></a>
                            </li>
                            <?php $cats_displayed++;
                        }
                    }
                }
                if ($cats_displayed == 0 || !$grand_children) {
                    $url = Mage::getModel('catalog/category')->load($subcat->getId())->getURL();
                    ?>
                    <li class="current<?php if ($subcat->getId() == $current_cat && $j == 0) {
                        $j++; ?> active<?php } ?>">
                        <a href="<?php echo $url ?>"><?php echo $subcat->getName() ?></a>
                    </li>
                <?php }
            }
        } ?>
    </ul>
</li>
<?php endif;?>
<?php endif;?>
<?php endforeach; ?>

任何人都可以向我提供一些关于如何使这个FAR更高效并且不进行如此多的数据库调用的指针。

应该注意,我不是一个令人惊讶的php开发者。主要的语言是python,所以我试图获得一些关于修复这个问题的最佳方法的建议,因为我对php本身的了解不多。

答案

你永远不应该在for循环中进行数据库查询调用。您需要在开始时构建一个查询,以获取for循环之前所需的所有数据。

我能看到的一些即时指针是:

$grand_child_show = Mage::getModel('catalog/category')->load($grand_child->getId());
                        if ($grand_child_show->getShowSidebar() == 1) {
                            $url = Mage::getModel('catalog/category')->load($grand_child_show->getId())->getURL();

这是无缘无故地调用数据库两次,你应该能够这样做:

 $grand_child_show = Mage::getModel('catalog/category')->load($grand_child->getId());
                            if ($grand_child_show->getShowSidebar() == 1) {
                                $grand_child_show->getURL();

你应该能够删除所有这些'GetModel'函数,如果在脚本开头你调用类似的东西:

$all_grand_children = Mage::getModel('catalog/category')->getAllCategories();

这将返回一个哈希数组,您可以通过在for循环中执行以下操作来访问相关项:

$grand_children = $all_grand_children[$subcat->getId()];

这将取代

$grand_children = Mage::getModel('catalog/category')->getCategories($subcat->getId());

您还应该对所有grand_child和cat_show对象进行初始调用。如果您熟练使用SQL,则可以通过在一个SQL查询中连接表来调用相关信息。

以上是关于For循环正在进行3600个数据库请求以加载产品。 PHP的主要内容,如果未能解决你的问题,请参考以下文章

Vue:检索 Firestore 数据以显示用户的企业名称 v-for 循环

for循环中的多个选择字符串以分隔文件

优化 FOR 循环中的请求

在python中使用for循环时出现JSONDecodeError [重复]

ffmpeg/for 循环:如何使 ffmpeg 或 cmd 循环在发现错误后停止?

对具有相同结构的几个数据集使用lapply并可能进行for循环以提取和计算每个数据帧的值