繁体   English   中英

你如何优化这个半复杂的mysql查询?

[英]how do you optimize this semi-complex mysql query?

问候伙伴们!

这是db模式(简化为相关领域),以帮助说明我的难题:

在此输入图像描述

  • item_options具有itemsitems具有item_options
  • 同一item可以出现在多个categories
  • categoriesitemsitem_options都可以是活动的或非活动的(BOOL)。

类别看起来像这样(请注意parent_id嵌套,其中Fruit Seeds位于种子内部):

id   parent_id   name              active
 1           0   Seeds                  1
 2           1   Vegetable Seeds        1
 3           1   Fruit Seeds            0
 4           0   Plants                 1
 5           4   Vegetable Plants       1
 6           4   Fruit Plants           1

我想要的是所有活动类别(id,parent_id和name)的快速列表,以及包含活动item_options的每个类别的活动项目的计数。

查询结果如下所示:

id   parent_id   name              item_count
 1           0   Seeds                      0
 2           1   Vegetable Seeds           52
 4           0   Plants                     0
 5           4   Vegetable Plants         103
 6           4   Fruit Plants              79

此查询有效, 但需要约430毫秒

    SELECT c.`id`, c.`parent_id`, c.`name`,
        (SELECT COUNT(*)
            FROM `item_categories` AS ic
            LEFT JOIN `items` AS i
                ON (i.`id` = ic.`item_id`)
            LEFT JOIN `item_options` AS io
                ON (i.`id` = io.`item_id`)
            WHERE c.`id` = ic.`category_id`
                AND i.`active` = 1
                AND io.`active` = 1
            ) AS `item_count`
    FROM `categories` AS c
    WHERE c.`active` = 1;

下一个查询只需要〜55ms,但无法包含顶级类别(其中parent_id = 0):

    SELECT c.`id`, c.`parent_id`, c.`name`,
        COUNT(ic.`item_id`) AS `item_count`
    FROM `categories` AS c
    LEFT JOIN `item_categories` AS ic
        ON (c.`id` = ic.`category_id`)
    LEFT JOIN `items` AS i
        ON (i.`id` = ic.`item_id`)
    LEFT JOIN `item_options` AS io
        ON (i.`id` = io.`item_id`)
    WHERE c.`active` = 1
      AND i.`active` = 1
      AND io.`active` = 1
    GROUP BY c.`id`;

有人看到如何加快第一个查询,或修复第二个查询?

哦! 这似乎做到了......

(
    SELECT c.`id`, c.`parent_id`, c.`name`,
        COUNT(ic.`item_id`) AS `item_count`
    FROM `categories` AS c
    LEFT JOIN `item_categories` AS ic
        ON (c.`id` = ic.`category_id`)
    LEFT JOIN `items` AS i
        ON (i.`id` = ic.`item_id`)
    LEFT JOIN `item_options` AS io
        ON (i.`id` = io.`item_id`)
    WHERE c.`active` = 1
      AND i.`active` = 1
      AND io.`active` = 1
    GROUP BY c.`id`
)
UNION
(
    SELECT c.`id`, c.`parent_id`, c.`name`, 0
    FROM `categories` AS c
    WHERE c.`parent_id` = 0
      AND c.`active` = 1
)
ORDER BY `parent_id`, `NAME`;

有谁看到更好的方式? :d

暂无
暂无

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

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