我需要一些SQL帮助。我有一个SELECT语句,它引用了几个表,并且正在MySQL数据库中挂起。我想知道是否有更好的方法来写这个语句,这样它就可以高效地运行并且不会挂掉DB?如有任何帮助/指导,将不胜感激。谢谢。
以下是代码:
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错误。抱歉的。
发布于 2014-06-11 19:54:55
提示:使用显式联接,而不是用逗号分隔的表列表。通过这种方式可以更容易地看出您正在使用的逻辑。重写您的查询以完成此操作将给我们提供以下信息。
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开始。您正在使用Forename、Surname和DOB的特定值进行筛选。您正在使用一系列的ApplicationDate值进行筛选。最后,您需要AppID来管理您的连接。因此,这个复合指数应该会有所帮助。它的列以正确的顺序使用距离扫描来满足您的查询,并包含所需的结果。
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)这种索引称为复合覆盖指数,可以极大地加快您所询问的摘要查询的速度。
https://stackoverflow.com/questions/24170966
复制相似问题