简体   繁体   English

MySQL中的查询优化

[英]Query optimization in MySQL

At first, i have to say that this topic is very common topic. 首先,我不得不说这个话题是非常常见的话题。 I have studied all related topics but i can not find out the answer. 我已经研究了所有相关主题,但我找不到答案。 I have three tables. 我有三张桌子。 Messages table has 300.000, tags table has 1 million and message_tag table has about 10 million rows. 消息表有300.000,标签表有100万,message_tag表有大约1000万行。 message_tag.message_id and message_tag.tag_id columns have indexes. message_tag.message_id和message_tag.tag_id列具有索引。 My purpose is select messages which linked a spesified tag. 我的目的是选择链接特定标签的消息。 However query times are too long. 但是查询时间太长。 There is not any query time shorter than 20 seconds. 没有任何查询时间短于20秒。 On the other hand sometimes query does not give even a result due to long query times. 另一方面,由于查询时间长,有时查询不会给出结果。 Table structures and my query are below. 表结构和我的查询如下。 How can i handle this problem? 我该如何处理这个问题? I am open all suggestions. 我打开所有的建议。 Even i can recreate tables with a new schema. 即使我可以使用新架构重新创建表。 Database is MySql, Storage motor is MyIsam. 数据库是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)

My query: 我的查询:

SELECT                    messages.message_poster,
                          messages.message
                     FROM tags, messages, message_tag 
                     WHERE message_tag.tag_id=191
                     AND messages.id= message_tag.message_id

And here is an example of why I don't like using , notation. 而这就是为什么我不喜欢使用的例子,表示法。

You don't relate message_tag to tags . 您没有将message_tagtags相关联。 Instead, you join EVERY message tag to every other row. 相反,您将每个消息标记加入到每个其他行。

This is what you have... 这就是你拥有的......

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

This is what you should have... 这就是你应该拥有的......

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

(Or, just don't JOIN on tags at all, you're not using it in this case. Though I appreciate that this may be a simplified version of the actual query.) (或者,根本不要在tags上加入,在这种情况下你不会使用它。虽然我知道这可能是实际查询的简化版本。)

It's much harder to mess that up with ANSI-92 notation. 使用ANSI-92表示法更加困难。

Create a two-dimensional index on message_tag (over both fields), and rewrite the WHERE to 在message_tag上创建一个二维索引(在两个字段上),并将WHERE重写为

WHERE 
    message_tag.tag_id=191 AND 
    message_tag.message_id = messages.id

我想你错过了两个表之间的连接条件,可能是tagsmessage_tag

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM