【发布时间】:2025-12-02 19:20:03
【问题描述】:
我在一个存储过程中有一个查询,它从我的 SQL Server 数据库的几个表中检索数据。在我的应用程序中,我使用一些参数调用这个存储过程来过滤数据。
奇怪的是,对于一年中“X”周返回的所有数据(大约 2600 条记录),检索数据大约需要 30 秒。但是如果我为一年中的同一周添加一个特定的“中心”过滤器(大约 1800 条记录),大约需要 3 分钟才能获取数据!
如果我只运行查询,它运行良好(所有数据 30 秒,过滤数据大约 22 秒)。问题是当我通过存储过程运行查询时!
这怎么可能?为什么过滤后的数据比获取所有数据需要大约 x6 倍?为什么我失踪了?我是否正确编写存储过程?我怎样才能以更有效的方式做到这一点?
我的存储过程代码是这样的:
ALTER PROCEDURE EventMonitoring
@EventType AS CHAR(1),
@Year AS INT,
@Week AS INT,
@CenterID AS CHAR(2),
@AreaID AS INT
AS
DECLARE @SQLCommand AS VARCHAR(MAX)
DECLARE @MessageError AS VARCHAR(MAX)
SET @SQLCommand = ' SELECT ....
....
....
....
FROM Event E
INNER JOIN ...
INNER JOIN ...
INNER JOIN ...
WHERE E.EventYear = ' + CAST(@Year AS VARCHAR) +
' And E.EventWeek = ' + CAST(@Week AS VARCHAR) +
' And E.EventType = ' + CAST(@EventType AS VARCHAR)
IF @Centro <> '-' --If application sends - as the parameter, it gets all centers
BEGIN
@SQLCommand = @SQLCommand + ' AND E.CenterID = ''' + @CenterID + ''''
END
IF @Area <> 0 --If application sends 0 as the parameter, it gets all areas
BEGIN
@SQLCommand = @SQLCommand + ' AND E.AreaID = ' + CAST(@AreaID AS VARCHAR)
END
SET @SQLCommand = @SQLCommand + 'GROUP BY ....'
BEGIN TRY
EXEC(@SQLCommand)
END TRY
BEGIN CATCH
....
END CATCH
【问题讨论】:
-
你能显示表结构和索引吗?表格有多少行?
-
当您使用
DBCC FREEPROCCACHE在 proc 之外运行查询时会发生什么?执行时间是否更接近您的 SP 执行时间? -
向我们展示两个计划? brentozar.com/pastetheplan
-
它来自 ADO 连接?
-
好的,我会试着给你看表,但是就像我说的,它有很多表,无论如何,如果是索引或表结构问题,为什么查询本身可以正常工作为什么当我将查询放在 SP 上时需要更长的时间?是的,它来自 ADO,但无论如何,如果我直接运行 SP,也会发生同样的情况
标签: sql-server stored-procedures