【发布时间】:2012-08-24 23:59:12
【问题描述】:
我的数据库中有 5 个表。
[项目] - id、名称等...
[类别] - id、名称
[标签] - id、姓名
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
【问题讨论】:
-
GROUP_CONCAT 首先,然后加入。使用子查询。
-
找到性能最佳的查询绝非易事。使用 Explain 为您的查询添加前缀并运行它,并将结果放入您的问题中,我们现在所能做的就是猜测。
-
子查询对我的查询编写来说几乎总是一个危险信号。此外,我认为有一些“简单”的技术可以让你获得一个非常高效的基础。真正困难的部分是对性能进行超级调整。但在有数百万行之前,我还没有注意到对它的真正需求(通过精心设计的查询)。 10 次中有 9 次,简单地了解如何根据您的 sql 构建查询计划将使您编写的查询效率提高许多数量级(如果您的架构很好的话)。
-
哦,我不推荐子查询,但我也不推荐猜测。 :( 除非它是一个非常明显的缺失索引)解释是工作之一。如果它是一个明显的索引,那么解释是第二个工作,只是为了确保我和 DBMS 在同一页面上。
-
@ctrahey:我自己说得再好不过了。 :)
标签: php mysql sql codeigniter join