如何在大循环中使用时优化COUNT()

时间:2018-03-09 05:53:42

标签: php mysql codeigniter query-optimization

我有一种情况,我会显示这些类别,以及那些和所有内部子和子类别中的产品数量(仅限3级)

这是我的SQL语句

SELECT COUNT(id) as count_brand_prod FROM `shop_products` 
WHERE (`shop_products`.`category_id` IN (28,59,29,60,30,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,27)
OR `shop_products`.`parent_category_id` = '27') 
AND `brand_id` = '88' 
AND `pharmacy_id` = '10';

我在父类别和子类别上循环它,也使用上述查询为每个类别计算类别和该类别的任何级别中存在的产品数量。我之所以使用IN运算符,其中包含所有类别/子类别和子级别的ID。

虽然循环播放会降低页面访问速度。任何人都可以帮助我如何优化查询以更快地加载我的页面?

5 个答案:

答案 0 :(得分:0)

确保所有ID列都已编入索引,即。有钥匙。
如果不添加缺失索引,例如使用此alter table query:

ALTER TABLE `shop_products`
ADD INDEX `id` (`id`),
ADD INDEX `category_id` (`category_id`),
ADD INDEX `parent_category_id` (`parent_category_id`),
ADD INDEX `brand_id` (`brand_id`),
ADD INDEX `pharmacy_id` (`pharmacy_id`)
;

注意:首先删除已存在索引的行!

答案 1 :(得分:0)

为避免缓慢,您可以使用连接或子查询。

(shop_products.category_id IN (28,59,29,60,30,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,27)
在另一个表中,这些类别id的父ID应该可以使用join。

答案 2 :(得分:0)

如果在循环中只更改查询中的parent_category_id,请计算按parent_category_id分组的所有内容:

SELECT `parent_category_id`, COUNT(id) as count_brand_prod FROM `shop_products` 
WHERE `category_id` IN (28,59,29,60,30,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,27)
AND `brand_id` = '88' 
AND `pharmacy_id` = '10'
GROUP BY `parent_category_id`;

因此,您将只有一个查询,其余的计算将在PHP中处理。

答案 3 :(得分:0)

复合adb shell pm grant将优于单个索引。它将有助于查询性能。

答案 4 :(得分:0)

添加以下复合和覆盖索引:

ALTER TABLE `shop_products` ADD INDEX `shop_products_idx_id_id_id` (`brand_id`, `pharmacy_id`, `id`);

此外,删除数字字段周围的单引号,这可能会导致不必要的强制转换,这可能会阻止索引使用。

因此,索引后应运行的查询是:

SELECT
        COUNT(`shop_products`.id) AS count_brand_prod 
    FROM
        `shop_products` 
    WHERE
        (
            `shop_products`.`category_id` IN (
                28, 59, 29, 60, 30, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 27
            ) 
            OR `shop_products`.`parent_category_id` = 27
        ) 
        AND `shop_products`.`brand_id` = 88
        AND `shop_products`.`pharmacy_id` = 10