【问题标题】:SQL Server 100% CPU when running a Stored Procedure with date filtering运行带有日期过滤的存储过程时 SQL Server 100% CPU
【发布时间】:2016-03-09 15:12:18
【问题描述】:

我遇到这个问题已经有一段时间了,我一生都无法弄清楚是什么原因造成的,所以希望有人能提供帮助。

这是我的存储过程

ALTER PROCEDURE [Report].[Purchasing_PickRateAndSales]
@StartDate nvarchar(50),
@EndDate nvarchar(50),
@Branch nvarchar(50)

AS
BEGIN
    SET NOCOUNT ON;

    SELECT
        ILines.Part,
        Product.[Desc],
        Count(ILines.Qty) AS Frequency,
        Sum(ILines.Qty) AS Quantity,
        Month([ILines].[DateTime]) AS [Month],
        ILines.Branch

    FROM
        Autopart.dbo.ILines
        LEFT JOIN Autopart.dbo.Product ON ILines.Part = Product.KeyCode
        INNER JOIN Autopart.dbo.IHeads ON ILines.Document = IHeads.Document

    WHERE
        (ILines.[DateTime] BETWEEN CONVERT(datetime, @StartDate, 103) AND CONVERT(datetime, @EndDate, 103))

    GROUP BY
        ILines.Part,
        Product.[Desc],
        Month([ILines].[DateTime]),
        ILines.Branch

    HAVING
        (ILines.Branch LIKE @Branch)

    ORDER BY
        ILines.Part,
        Month([ILines].[DateTime])

END

请原谅 nvarchar 的开始和结束日期,但作为参考,我也尝试过使用 datetime。

我使用带有 SQLSRV 驱动程序的 PHP 连接并运行存储过程,日期当前以 dd/mm/yyyy 格式传递,但我尝试使用 php 函数 DateTime::createFromFormat(); 将其作为日期时间传递,但没有成功

每次我运行这样的程序时,它都会使服务器达到 100% cpu,并且在我停止查询之前永远不会超时或完成。

为了排除 SQL 问题,我手动将参数插入到存储过程中,该过程立即生效,因此我认为这是 php 或驱动程序问题

如果您需要更多信息,请告诉我

更新:

查看 cmets 中发布的文章后,我发现参数嗅探似乎是造成这种情况的原因,我已经实现了以下现在可以完美运行的内容

ALTER PROCEDURE [Report].[Purchasing_PickRateAndSales]
@StartDate datetime,
@EndDate datetime,
@Branch nvarchar(50)

AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @SD datetime
    DECLARE @ED datetime

    SET @SD = @StartDate
    SET @ED = @EndDate

    SELECT
        ILines.Part,
        Product.[Desc],
        Count(ILines.Qty) AS Frequency,
        Sum(ILines.Qty) AS Quantity,
        Month([ILines].[DateTime]) AS [Month],
        ILines.Branch

    FROM
        Autopart.dbo.ILines
        LEFT JOIN Autopart.dbo.Product ON ILines.Part = Product.KeyCode
        INNER JOIN Autopart.dbo.IHeads ON ILines.Document = IHeads.Document

    WHERE
        (ILines.[DateTime] BETWEEN @SD AND @ED)

    GROUP BY
        ILines.Part,
        Product.[Desc],
        Month([ILines].[DateTime]),
        ILines.Branch

    HAVING
        (ILines.Branch = @Branch)

    ORDER BY
        ILines.Part,
        Month([ILines].[DateTime])

【问题讨论】:

  • 你能摆脱LIKE吗?喜欢往往是一个非常“贪婪”的过程。如果您可以选择特定的分支或分支组,那就太好了。如果你有一个带有 HAVING 的 WHERE,我可以看到另一个问题 - 这也可能会影响性能。
  • 为什么将日期时间值作为 varchars 传递?为什么不让您的参数成为日期时间?
  • @Leptonator 的编码方式与 = 相同,因为那里没有通配符。
  • 这几乎肯定是参数嗅探的问题。这是一篇关于该主题的优秀文章。 sqlinthewild.co.za/index.php/2007/11/27/parameter-sniffing
  • 在 SQL Studio 中使用性能分析器怎么样?巨大的或猪的流程要去哪里?

标签: php sql-server datetime stored-procedures


【解决方案1】:

您所描述的行为听起来像是参数嗅探的典型案例。尤其是当它使用过程中声明的值运行超快时的部分。有关参数嗅探的更深入解释,请参阅本文。 http://sqlinthewild.co.za/index.php/2007/11/27/parameter-sniffing/

【讨论】:

  • 感谢您快速而有帮助的回复肖恩,我已经用完成的程序编辑了我的问题,现在可以使用了
猜你喜欢
  • 2014-09-04
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2020-02-24
  • 2016-04-28
相关资源
最近更新 更多