0

我的数据库中有 5 个表。
[Items] - id、name 等...
[Categories] - id、name
[Tags] - id、name

2 连接表
[Items_Categories] - item_id, category_id
[Items_Tags] - item_id, tag_id

在给定 item_id = $id 的情况下,我只需要知道性能最佳的查询(必要时使用 JOINS)即可从数据库中提取 1 个或多个项目及其所有信息,包括类别和标签。

到目前为止,我有以下工作,但在 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 回答