How do I pull both categories AND tags from a MySQL Database for an item?

I have 5 tables in my database.
[Items] - id, name, etc...
[Categories] - id, name
[Tags] - id, name

2 Joining tables
[Items_Categories] - item_id, category_id
[Items_Tags] - item_id, tag_id

I simply need to know the best performing query (using JOINS as necessary) to pull 1 or more items from the DB WITH all of it's information, including the Categories AND Tags, given the item_id = $id.

So Far, I have the following which works, but on 25 - 50 queries, it was slow (Does anyone have something better?):

    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

The problem is that you are actually doing a full cross join first (by listing the tables the way you did) instead of joining selectively "in order" and allowing the joins to be streamlined by the query plan. Try joining like this to explicitly join only the appropriate rows as it goes.

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`

This will yield a lightening-fast query, and it is easily made even faster by adding the appropriate indexes. My philosophy, however, is that you should have a fast query first, and then get it wicked fast with indexing; not using indexes as a first-approach.

链接地址: http://www.djcxy.com/p/63800.html

上一篇: MySQL:null在INSERT和SELECT语句中变为0

下一篇: 如何从一个MySQL数据库中为一个项目提取两个类别和标签?