0

MySQL を使用してこれまでに作成した最長のクエリを最適化しようとしていますEXPLAINが、これが初めてなので、結果を理解できないようです。クエリとEXPLAINコマンドを実行した結果は次のとおりです。

EXPLAIN SELECT pb.name, s1.MessageFrom, s1.MessageText, s1.SendTime, s1.is_unread, s1.Id, s1.autoreply_sent FROM sol_inbound s1
    JOIN sol_contactnum c ON s1.MessageFrom = c.number
    JOIN sol_phonebk_contactnum USING (contactnum_id)
    JOIN sol_phonebk pb USING (phonebk_id)
    JOIN sol_message_folder mf ON s1.Id = mf.message_id
    WHERE (MessageFrom, SendTime) IN (SELECT MessageFrom, MAX(SendTime) FROM sol_inbound inb
        JOIN sol_message_folder mf WHERE inb.Id = mf.message_id
        AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
        GROUP BY MessageFrom)
    AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
    UNION
    SELECT NULL `name`, s1.MessageFrom, s1.MessageText, s1.SendTime, s1.is_unread, s1.Id, s1.autoreply_sent FROM sol_inbound s1
    LEFT JOIN sol_contactnum c ON s1.MessageFrom = c.number
    JOIN sol_message_folder mf ON s1.Id = mf.message_id
    WHERE c.number IS NULL
    AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
    AND (MessageFrom, SendTime) IN (SELECT MessageFrom, MAX(SendTime) FROM sol_inbound inb
        JOIN sol_message_folder mf WHERE inb.Id = mf.message_id
        AND mf.folder_id=1 AND mf.direction='inbound' AND mf.user_id=1
        GROUP BY MessageFrom)
    ORDER BY SendTime DESC LIMIT 100

EXPLAIN結果は次のとおりです。

 id  select_type         table                   type    possible_keys                                                  key               key_len  ref                                                     rows  Extra                   
------  ------------------  ----------------------  ------  -------------------------------------------------------------  ----------------  -------  ----------------------------------------------------  ------  ------------------------
     1  PRIMARY             pb                      ALL     PRIMARY                                                        (NULL)            (NULL)   (NULL)                                                   303                          
     1  PRIMARY             sol_phonebk_contactnum  ref     PRIMARY,phonebk_id1_idx,contactnum_id1_idx,phonebk_contactnum  PRIMARY           4        googlep1_solane.pb.phonebk_id                              1  Using index             
     1  PRIMARY             c                       eq_ref  PRIMARY,number_idx                                             PRIMARY           4        googlep1_solane.sol_phonebk_contactnum.contactnum_id       1                          
     1  PRIMARY             s1                      ref     PRIMARY,message_from_idx                                       message_from_idx  243      googlep1_solane.c.number                                   1  Using where             
     1  PRIMARY             mf                      eq_ref  PRIMARY                                                        PRIMARY           22       const,googlep1_solane.s1.Id,const,const                    1  Using where; Using index
     2  DEPENDENT SUBQUERY  inb                     index   PRIMARY                                                        message_from_idx  243      (NULL)                                                     1                          
     2  DEPENDENT SUBQUERY  mf                      eq_ref  PRIMARY                                                        PRIMARY           22       const,googlep1_solane.inb.Id,const,const                   1  Using where; Using index
     3  UNION               s1                      ALL     PRIMARY                                                        (NULL)            (NULL)   (NULL)                                                   877  Using where             
     3  UNION               c                       ref     number_idx                                                     number_idx        243      googlep1_solane.s1.MessageFrom                             1  Using where; Using index
     3  UNION               mf                      eq_ref  PRIMARY                                                        PRIMARY           22       const,googlep1_solane.s1.Id,const,const                    1  Using where; Using index
     4  DEPENDENT SUBQUERY  inb                     index   PRIMARY                                                        message_from_idx  243      (NULL)                                                     1                          
     4  DEPENDENT SUBQUERY  mf                      eq_ref  PRIMARY                                                        PRIMARY           22       const,googlep1_solane.inb.Id,const,const                   1  Using where; Using index
(NULL)  UNION RESULT        <union1,3>              ALL     (NULL)                                                         (NULL)            (NULL)   (NULL)                                                (NULL)  Using filesort          

クエリのUNION真ん中にある は、電話帳に番号が表示されている人と表示されていない人を結合します (したがってLEFT JOIN)。

編集:

このクエリが行うことは、各番号の最新のインバウンド メッセージを取得して返すことです。GROUP BY最も古いメッセージを返すので使用できます...最新のメッセージが必要です。次に、電話帳に存在しない番号を結合します。これが、私がチェックする理由ですWHERE c.number IS NULL.

4

2 に答える 2