【发布时间】:2011-03-18 03:05:25
【问题描述】:
我有一个关于基本 mysql 数据库优化的问题。 我有 3 个表,Articles、Tags 和 Taggings(这是一个连接表)。
Articles Taggings Tags
id id id
name article_id name
tag_id
我正在使用以下查询检索与指定标签完全匹配的文章
SELECT *, COUNT(*) AS c
FROM articles AS a
JOIN taggings AS tng ON a.id = tng.article_id
JOIN tags AS t ON t.id = tng.tag_id
WHERE t.name IN ("Red","Green")
GROUP BY a.id
HAVING c = 2
这个查询很慢,所以我做了一个EXPLAIN,得到了如下结果:
alt text http://dl.dropbox.com/u/2306276/EXPLAIN%20results.png
现在,我不太明白我在这里做什么,但我认为“type: ALL”不好,所以我想我会在 taggings 表中的 article_id 和 tag_id 中添加索引(BTREE),并且再次运行查询。 alt text http://dl.dropbox.com/u/2306276/EXPLAIN%20results%202.png 好吧,在我未受过教育的人看来,这看起来并没有更好,行数与前一个相同,并且在两种情况下类型仍然是 ALL。
那么有人可以告诉我哪里出错了吗?索引不会帮我解决这个问题吗?
我的 Tag 表会保持相对较小,所以我认为查询应该扫描 Tag 表以查找我指定的标签,然后(通过索引)能够立即检索到关联的属性,并且应该都非常很快,显然我的想法有问题。
谢谢
[编辑] - 杰伊的 cmets
我加了10k篇文章,30k个taggings,6个tags,还在tag.name和taggings.tag_id上加了2个索引,查询还是跑了很长时间,0.5-1秒,下面是EXPLAIN。 alt text http://dl.dropbox.com/u/2306276/EXPLAIN%20results%203.png
【问题讨论】:
-
你有 tags.name 的索引吗?如果您的数据库有很多记录,这可能会有所帮助
-
@Naktibalda,我还没有索引 tags.name,因为在实际应用中大约有 100 个标签,10000 篇文章和 50000 个标签。
-
OMG Ponies:感谢您的链接,我一直担心在 GROUP BY 中仅使用 id 字段是一件坏事
-
@OMG Ponies,在这种情况下是否有替代 GROUP BY 的方法?
标签: sql mysql optimization indexing