4

フロースタッカーの皆さん、こんにちは!

これが私の難問を説明するのに役立つdbスキーマ(関連するフィールドに縮小された)です:

ここに画像の説明を入力してください

  • ウェブストアには、、がitemsありitemsますitem_options
  • 同じitemことが複数に現れる可能性がありますcategories
  • categoriesitemsおよびitem_optionsすべてアクティブまたは非アクティブ(BOOL)にすることができます。

カテゴリは次のようになります(FruitSeedsがSeeds内にあるparent_idのネストに注意してください)。

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;

この次のクエリは約55ミリ秒しかかかりませんが、最上位のカテゴリ(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`;

最初のクエリを高速化する方法、または2番目のクエリを修正する方法を知っている人はいますか?

4

1 に答える 1

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`
)
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

于 2012-09-27T12:37:28.673 に答える