首先,我不得不说这个话题是非常普遍的话题。我已经研究了所有相关主题,但我找不到答案。我有三张桌子。消息表有 300.000,标签表有 100 万行,message_tag表有大约 1000 万行。message_tag.message_id 和 message_tag.tag_id 列都有索引。 我的目的是选择链接特定标签的消息。但是,查询时间太长。没有任何查询时间短于 20 秒。另一方面,有时由于查询时间长,查询甚至无法给出结果。表结构和我的查询如下。我该如何处理这个问题?我愿意接受所有建议。即使我也可以使用新架构重新创建表。数据库是MySql,存储电机是MyIsam。.
table name: messages
columns :
id (int)
message (vharchar)
message_poster (vharchar)
table name: tags
id (int)
tag (vharchar)
table name : message_tag
columns :
message_id (int)
tag_id (int)
我的查询:
SELECT messages.message_poster,
messages.message
FROM tags, messages, message_tag
WHERE message_tag.tag_id=191
AND messages.id= message_tag.message_id
这里有一个例子说明为什么我不喜欢使用,
符号。
你没有message_tag
与tags
联系起来. 相反,您将每个消息标记连接到每隔一行。
这就是你所拥有的...
SELECT
messages.message_poster,
messages.message
FROM
messages
INNER JOIN
message_tag
ON messages.id= message_tag.message_id
CROSS JOIN
tags
WHERE
message_tag.tag_id=191
这是你应该拥有的...
SELECT
messages.message_poster,
messages.message
FROM
messages
INNER JOIN
message_tag
ON messages.id = message_tag.message_id
INNER JOIN
tags
ON tags.id = message_tag.tag_id
WHERE
message_tag.tag_id = 191
(或者,根本不加入tags
,在这种情况下您没有使用它。 虽然我很欣赏这可能是实际查询的简化版本。
ANSI-92
符号来搞砸要困难得多。
在message_tag上创建一个二维索引(在两个字段上),并将 WHERE 重写为
WHERE
message_tag.tag_id=191 AND
message_tag.message_id = messages.id
我认为您在 2 个表之间缺少连接条件,也许是 tags
和 message_tag
?