2012-05-04 249 views
0

我有一个传统的PHP应用程序(不使用框架) - 在某些地方它有一些真正的放缓与一些查询需要8-10秒。优化MYSQL查询

下面是这些缓慢查询之一的提取,我可以看到我得到的文件指出,这是运行缓慢的原因(或至少我假设) - 任何人都可以建议如何优化我的查询,以防止使用filesort?该表有60万左右的行(因此其相当大的)

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 
+0

嗯......你的问题是格式不正确。 – Raptor

+2

你可以显示'MailList'和'MailList_Tags'表的模式吗? –

+1

600K比较小。你可能错过了一些索引。 –

回答

1

你需要一些指标:

  • 上表MailList_Tags

    ,上表MailList(Tag, MailListID)

  • 添加UNIQUE指数,请在(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 
+0

不是'(MailListId,Tag)'MailList_Tags上的主键吗? (渲染建议的唯一索引是不必要的) –

+1

你可以使它成为一个简单的索引,而不是唯一的。但是索引中的顺序是必需的。我在所有类似的多对多表(a,b)和'(b,a)'中总是有2个索引。 –

+0

@Matt:主键可能与此查询所需内容相反。 –