Frage

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. message_tag.message_id and message_tag.tag_id columns have indexes. 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. 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. .

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
War es hilfreich?

Lösung

And here is an example of why I don't like using , notation.

You don't relate message_tag to tags. 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.)

It's much harder to mess that up with ANSI-92 notation.

Andere Tipps

Create a two-dimensional index on message_tag (over both fields), and rewrite the WHERE to

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

I think you're missing a join condition between 2 tables, maybe tags and message_tag ?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top