SQL查询优化/整理有问题的查询

时间:2014-01-22 15:01:42

标签: sql sql-server

我希望有人可以查看下面的查询。我在运行的网站上遇到一些CPU问题,导致网站在高峰时段放慢速度。

当用户注册系统从一个1.8百万行的邮政编码表中选择Easting和Northing值时,我在这个表上设置了一个索引,并且相信它正在运行,但我还有另一个查询当我在执行计划中查看它时,显示成本相当高(某些部分为28%)。

下面的查询选择“帐户详细信息”,“用户星级评分的平均值”,并使用一个函数计算登录用户与所有结果之间的里程数,以显示最接近的第一个。

你能看到我把它放在一起的方式有什么明显的错误吗,我的SQL还可以,但有限,所以会感谢任何帮助,因为它是一个长期存在的问题。

SELECT  tblAccounts.accountID ,
        tblAccounts.city ,
        tblAccounts.emailAddress ,
        tblAccounts.paypalEmailAddress ,
        tblAccounts.skypeUsername ,
        tblAccounts.EA ,
        tblAccounts.postcode ,
        [onlineBootyUser].[fn_radialDistance](tblAccounts.EA, tblAccounts.NO,
                                              @EA, @NO) AS miles ,
        tblOrders.tableclothVisible ,
        ( SELECT    AVG(starRating) AS averageRating
          FROM      onlinebootyUser.tblStarRating
          WHERE     ( accountID = onlinebootyUser.tblOrders.accountID )
        ) AS starRating
FROM    tblOrders
        INNER JOIN tblAccounts ON tblOrders.accountID = tblAccounts.accountID
WHERE   ( tblAccounts.valid = 1 )
        AND ( ( tblOrders.orderStatus = 'Completed' )
              OR ( tblOrders.orderStatus = 'Pending' )
            )
        AND tblOrders.bootsaleDate = @bootsaleDate
        AND tblOrders.itemsAllowed > 0
        AND ( SELECT    COUNT(*)
              FROM      tblItems
              WHERE     tblItems.accountID = tblAccounts.accountID
                        AND tblItems.bootsaleDate = @bootSaleDate
            ) > 0
ORDER BY miles ASC

函数fn_radialDistance如下:

declare @d float;

        set @d = power(square(@east1-@east2)+square(@north1-@north2),0.5E)/1609.0E

        return @d

感谢您的期待!

1 个答案:

答案 0 :(得分:1)

这是您的查询格式,以便我可以阅读:

SELECT a.accountID, a.city, a.emailAddress, a.paypalEmailAddress, a.skypeUsername, a.EA,
       a.postcode,
       [onlineBootyUser].[fn_radialDistance](tblAccounts.EA, a.NO, @EA, @NO) AS miles,
       o.tableclothVisible,
       (SELECT AVG(starRating) AS averageRating
        FROM onlinebootyUser.tblStarRating sr
        WHERE sr.accountID = o.accountID
       ) AS starRating
FROM tblOrders o INNER JOIN
     tblAccounts a
     ON o.accountID = a.accountID
WHERE (a.valid = 1) AND (o.orderStatus in ('Completed', 'Pending')) AND
      o.bootsaleDate = @bootsaleDate AND o.itemsAllowed > 0 AND
      (SELECT count(*)
       FROM tblItems i
       WHERE i.accountID = a.accountID AND i.bootsaleDate = @bootSaleDate
      ) > 0
ORDER BY miles ASC

出现的问题是你拥有的索引。以下索引应该有所帮助:

tblItems(accountID, bootsaleDate);
tblStarRating(accountID, starRating);

您可以通过将where替换为exists,使exists (select 1 from tblItems i where i.accountID = a.accountID and i.bootsaleDate = @bootSaleDate ) 中的子查询更有效:

{{1}}

这可能是一个小小的改进,除非比赛的数量非常高。

除此之外,您还可以提供执行计划。函数调用很可能会损害性能。