0

データベースに 5 つのテーブルがあります。
[アイテム] - ID、名前など
[カテゴリ] - ID、名前
[タグ] - ID、名前

2 テーブルの結合
[Items_Categories] - item_id、category_id
[Items_Tags] - item_id、tag_id

item_id = $id を指定して、カテゴリとタグを含むすべての情報を使用して DB から 1 つ以上のアイテムを取得するために、(必要に応じて JOINS を使用して) 最もパフォーマンスの高いクエリを知る必要があるだけです。

これまでのところ、次のように動作しますが、25 ~ 50 のクエリでは低速でした (誰かもっと良いものはありますか?)。

    SELECT `items`.`name`, `items`.`etc`,
group_concat(DISTINCT categories.name ORDER BY categories.name DESC SEPARATOR ", ") AS category, 
group_concat(DISTINCT tags.name ORDER BY tags.name DESC SEPARATOR ", ") AS tag, 
`items`.`id` AS id 
FROM (`items` AS items, `item_categories` AS categories, `items_to_categories` AS items_cats, `item_tags` AS tags, `items_to_tags` AS items_tags) 
JOIN `item_categories` ON `categories`.`id` = `items_cats`.`category_id` AND items_cats.item_id = $id 
JOIN `item_tags` ON `tags`.`id` = `items_tags`.`tag_id` AND items_tags.item_id = $id WHERE `items`.`id` = $id
4

1 に答える 1

2

問題は、「順番に」選択的に結合し、クエリ プランによって結合を合理化できるようにするのではなく、実際に最初に完全なクロス結合を行っていることです (テーブルをリストすることによって)。このように結合して、適切な行だけを明示的に結合してみてください。

SELECT 
  `items`.`name`, 
  `items`.`etc`,
  group_concat(DISTINCT `categories`.`name` ORDER BY `categories`.`name` DESC SEPARATOR ", ") AS category, 
  group_concat(DISTINCT `tags`.`name` ORDER BY `tags`.`name` DESC SEPARATOR ", ") AS tag, 
  `items`.`id` AS id 
FROM `items`, 
  LEFT JOIN `item_categories` ON `items`.`id` = `item_categories`.`item_id`
  LEFT JOIN `categories` ON `item_categories`.`category_id` = `categories`.`id`,
  LEFT JOIN `item_tags` ON `items`.`id` = `item_tags`.`item_id`
  LEFT JOIN `tags` ON `item_tags`.`tag_id` = `tags`.`id` 
WHERE `item`.`id` = $id
GROUP BY `item`.`id`

これにより非常に高速なクエリが生成され、適切なインデックスを追加することで簡単にさらに高速化できます。ただし、私の哲学では、最初に高速なクエリを作成し、次にインデックスを作成して高速化する必要があります。最初のアプローチとしてインデックスを使用しない。

于 2012-08-25T00:17:21.343 に答える