0

私はレガシーPHPアプリケーション(フレームワークを使用していません)を持っています-場所によっては、いくつかのクエリが8〜10秒かかるという実際の速度低下があります。

以下は、これらの遅いクエリの1つからの抜粋です。これは、ファイルソートが取得されていることを示しています。これは、理由(または少なくとも私が推測する)で実行が遅いことを示しています。ファイルソートの使用を防ぐためにクエリを最適化する方法を誰かが提案できますか?テーブルには約600,000行あります(かなり大きいので)

Schema added:
(MailList_Tags)
Field   Type    Null    Key Default Extra
MailListID  int(11)     PRI 0    
Tag varchar(60)     PRI      

(MailList)    
Field   Type    Null    Key Default Extra
MailListID  int(11)     PRI NULL    auto_increment
GroupID varchar(8)  YES     NULL     
HotelID varchar(8)  YES     NULL     
Title   varchar(20) YES     NULL     
FirstName   blob    YES     NULL     
LastName    blob    YES     NULL     
CompanyName varchar(200)    YES     NULL     
Address blob    YES     NULL     
Postcode    varchar(12) YES     NULL     
Country varchar(200)    YES     NULL     
Tel varchar(40) YES     NULL     
Fax varchar(40) YES     NULL     
Email   blob                 
md5digest   varchar(32)     UNI      
Sub1    int(1)      MUL 0    
Sub2    int(1)      MUL 0    
Sub3    int(1)      MUL 0    
OptInState  char(1)     MUL P    
UpdateDetailsState  char(1) YES     NULL     
Bounce  int(11)         0


EXPLAIN SELECT  `Tag` , COUNT( DISTINCT (
`MailList_Tags`.`MailListID`
) ) AS  `Count` 
FROM  `MailList` 
JOIN  `MailList_Tags` ON  `MailList`.`MailListID` =  `MailList_Tags`.`MailListID` 
WHERE HotelID =  'ca4b9ac9'
AND OptInState =  'V'
GROUP BY  `Tag`

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  MailList_Tags   index   MailListID  MailListID  64  NULL    962583  Using index; Using filesort
1   SIMPLE  MailList    eq_ref  PRIMARY,OptInState  PRIMARY 4   user_db.MailList_Tags.MailListID    1   Using where
4

1 に答える 1

1

いくつかのインデックスが必要です:

  • テーブルに、インデックスをMailList_Tags追加しますUNIQUE(Tag, MailListID)

  • テーブルMailListで、 にインデックスを追加します(OptInState, HotelID, MailListID)

次に、次のクエリを試してください ( に変更COUNT( DISTINCT MailList_Tags.MailListID )するとCOUNT(*)、同じ結果が得られるはずです)。

SELECT  Tag 
     ,  COUNT( * )
          AS  `Count` 
FROM  MailList 
  JOIN  MailList_Tags 
    ON  MailList.MailListID = MailList_Tags.MailListID 
WHERE  HotelID =  'ca4b9ac9'
  AND  OptInState =  'V'
GROUP BY  Tag

またはこれ:

SELECT  Tag 
     ,  COUNT(*)
          AS  `Count` 
FROM  MailList 
WHERE  EXISTS 
       ( SELECT  *
         FROM  MailList_Tags 
         WHERE  MailList.MailListID = MailList_Tags.MailListID 
           AND  HotelID =  'ca4b9ac9'
           AND  OptInState =  'V'
       )
GROUP BY  Tag
于 2012-05-04T11:30:34.870 に答える