フロースタッカーの皆さん、こんにちは!
これが私の難問を説明するのに役立つdbスキーマ(関連するフィールドに縮小された)です:
- ウェブストアには、、が
items
ありitems
ますitem_options
。 - 同じ
item
ことが複数に現れる可能性がありますcategories
。 categories
、items
および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番目のクエリを修正する方法を知っている人はいますか?