5

このクエリは、約 10 万レコードのテーブルにあり、非常に遅く (3 ~ 4 秒) 実行されます。グループを取り出すと、はるかに高速 (0.5 秒未満) になります。これを修正するために何をすべきか、私はかなり迷っています:

SELECT msg.id,
       msg.thread_id,
       msg.senderid,
       msg.recipientid, 
       from_user.username AS from_name,
       to_user.username AS to_name
FROM msgtable AS msg
LEFT JOIN usertable AS from_user ON msg.senderid = from_user.id
LEFT JOIN usertabe AS to_user ON msg.recipientid = to_user.id
GROUP BY msg.thread_id
ORDER BY msg.id desc

msgtable には、、、および のインデックスthread_idがありidます。senderidrecipientid

返品について説明します:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  msg ALL NULL    NULL    NULL    NULL    162346  Using temporary; Using filesort
1   SIMPLE  from_user   eq_ref  PRIMARY PRIMARY 4   db.msg.senderid 1    
1   SIMPLE  to_user eq_ref  PRIMARY PRIMARY 4   db.msg.recipientid  1

同じ結果を返しながらこれを高速化する方法についてのアイデア (スレッドごとに複数のメッセージがあり、このクエリではスレッドごとに 1 つのメッセージのみを返したい)。

前もって感謝します。

4

2 に答える 2

1

これを試して:

select m.thread_id, m.id, m.senderid, m.recipientid, 
       f.username as from_name, t.username as to_name
from msgtable m
join usertable f on m.senderid = f.id
join usertable t on m.recipientid = t.id
where m.id = (select MAX(id) from msgtable where thread_id = m.thread_id)

またはこれ:

select m.thread_id, m.id, m.senderid, m.recipientid, 
       (select username from usertable where id = m.senderid) as from_name,
       (select username from usertable where id = m.recipientid) as to_name
from msgtable m
where m.id = (select MAX(id) from msgtable where thread_id = m.thread_id)

ユーザー テーブルが結合されたままになっているのはなぜですか? メッセージに from または to がないことはありますか?..

于 2010-10-26T16:28:57.787 に答える
0

最大の問題は、 に使用可能なインデックスがないことですmsgtable少なくとも senderidとにインデックスを作成するrecipientidと、スキャンする必要がある結果の数が制限されるため、クエリの速度が向上するはずです。

于 2010-10-26T17:11:40.737 に答える