0

我有一个遗留的 PHP 应用程序(不使用任何框架)——在某些地方它有一些真正的减速,一些查询需要 8-10 秒。

下面是这些慢查询之一的摘录,我可以看到我正在获取文件排序,这表明由于原因(或者至少我认为)运行缓慢 - 任何人都可以建议如何优化我的查询以防止使用文件排序?该表有大约 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 回答