SQL语句挂在MySQL数据库中

时间:2014-06-11 19:22:46

标签: mysql sql database-performance

我需要一些SQL帮助。我有一个SELECT语句引用了几个表,并挂在MySQL数据库中。我想知道是否有更好的方法来编写此语句,以便它有效地运行并且不会挂起数据库?任何帮助/方向将不胜感激。感谢。

以下是代码:

Select Max(b.BurID) As BurID 
From My.AppTable a, 
My.AddressTable c, 
My.BurTable b 
Where a.AppID = c.AppID 
And c.AppID = b.AppID 
And (a.Forename = 'Bugs' 
And a.Surname = 'Bunny' 
And a.DOB = '1936-01-16' 
And c.PostcodeAnywhereBuildingNumber = '999' 
And c.PostcodeAnywherePostcode = 'SK99 9Q9' 
And c.isPrimary = 1 
And b.ErrorInd <> 1  
And DateDiff(CurDate(), a.ApplicationDate) <= 30)

日志中没有mysql错误。遗憾。

1 个答案:

答案 0 :(得分:3)

专业提示:使用显式JOIN而不是以逗号分隔的表列表。通过这种方式更容易看到你用来加入的逻辑。重写您的查询以实现这一目标。

select Max(b.BurID) As BurID 
  From My.AppTable AS a 
  JOIN My.AddressTable AS c ON a.AppID = c.AppID 
  JOIN My.BurTable  AS b ON c.AppID = b.AppID
 WHERE (a.Forename = 'Bugs' 
   And a.Surname = 'Bunny' 
   And a.DOB = '1936-01-16' 
   And c.PostcodeAnywhereBuildingNumber = '999' 
   And c.PostcodeAnywherePostcode = 'SK99 9Q9' 
   And c.isPrimary = 1 
   And b.ErrorInd <> 1  
   And DateDiff(CurDate(), a.ApplicationDate) <= 30)

下一篇专业提示:不要在DateDiff()子句中使用函数(如WHERE),因为它们使用索引进行搜索失败。这意味着您应该将查询的最后一行更改为

  AND a.ApplicationDate >= CurDate() - INTERVAL 30 DAY

这与查询中的逻辑相同,但它在搜索表达式中留下了一个裸名称(因此可以索引搜索)。

接下来,我们需要查看您的列以查看您的搜索方式,并制作适当的索引。

让我们从AppTable开始吧。您要按ForenameSurnameDOB的具体值进行筛选。您正在通过一系列ApplicationDate值进行筛选。最后,您需要AppID来管理您的加入。所以,这个复合指数应该有所帮助。其列的顺序正确,可以使用range scan来满足您的查询,并包含所需的结果。

 CREATE INDEX search1 USING BTREE 
     ON AppTable 
        (Forename, Surname, DOB, ApplicationDate, AppID)

接下来,我们可以查看您的AddressTable。类似的逻辑适用。您将通过JOINed AppID输入此表,然后按三列的特定值进行筛选。所以,试试这个索引

 CREATE INDEX search2 USING BTREE 
     ON AddressTable 
        (AppID, PostcodeAnywherePostcode, PostcodeAnywhereBuildingNumber, isPrimary)

最后,我们将继续您的BurTable。使用与其他两个类似的逻辑,并尝试此索引。

 CREATE INDEX search3 USING BTREE 
     ON BurTable 
        (AppID, ErrorInd, BurID)

这种索引称为compound covering index,可以大大加快您询问的摘要查询的速度。