0

最初は、このトピックは非常に一般的なトピックであると言わざるを得ません。私はすべての関連トピックを研究しましたが、答えを見つけることができません。私は3つのテーブルを持っています。メッセージテーブルには300.000、タグテーブルには100万、message_tagテーブルには約1,000万行があります。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
4

3 に答える 3

2

,そして、これが私が記法を使うのが好きでない理由の例です。

message_tagあなたはに関係していませんtags。代わりに、すべてのメッセージタグを1行おきに結合します。

これはあなたが持っているものです...

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それを記法で台無しにするのははるかに難しいです。

于 2012-06-20T15:09:06.597 に答える
0

message_tagに(両方のフィールドで)2次元のインデックスを作成し、WHEREを次のように書き直します。

WHERE 
    message_tag.tag_id=191 AND 
    message_tag.message_id = messages.id
于 2012-06-20T15:06:20.933 に答える
0

2つのテーブル間の結合条件が欠落していると思います。多分tagsmessage_tag

于 2012-06-20T15:08:20.907 に答える