SQL Server - 存储过程突然变慢

时间:2010-03-17 12:58:21

标签: sql stored-procedures indexing spatial

我写了一个存储过程,昨天通常在一秒钟内完成。今天,大约需要18秒。我昨天遇到了问题,它似乎通过DROPing和重新创建存储过程来解决。今天,这个技巧似乎没有奏效。 :(

有趣的是,如果我复制存储过程的主体并将其作为简单的查询执行,则可以快速完成。这似乎是一个事实,它是一个缓慢下来的存储过程......!

有谁知道问题可能是什么?我已经搜索了答案,但他们经常建议通过查询分析器运行它,但我没有它 - 我现在正在使用SQL Server 2008 Express。

存储过程如下;

ALTER PROCEDURE [dbo].[spGetPOIs]
    @lat1 float,
    @lon1 float,
    @lat2 float,
    @lon2 float,
    @minLOD tinyint, 
    @maxLOD tinyint,
    @exact bit
AS
BEGIN
    -- Create the query rectangle as a polygon
    DECLARE @bounds geography;
    SET @bounds = dbo.fnGetRectangleGeographyFromLatLons(@lat1, @lon1, @lat2, @lon2);

    -- Perform the selection
    if (@exact = 0)
    BEGIN
        SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID]
        FROM [POIs]
        WHERE
            NOT ((@maxLOD  [MaxLOD])) AND
            (@bounds.Filter([Location]) = 1)
    END
    ELSE
    BEGIN
        SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID]
        FROM [POIs]
        WHERE
            NOT ((@maxLOD  [MaxLOD])) AND
            (@bounds.STIntersects([Location]) = 1)
    END

END

'POI'表有MinLOD,MaxLOD索引和位置空间索引。

3 个答案:

答案 0 :(得分:3)

啊,这可能是查询计划糟透了吗?

SP的编译/查询lpan在FIRST USE上确定 - 取决于参数。因此,第一个调用的参数(当没有lpan时)确定查询计划。有一次,我从缓存中删除了新计划。

下次运行缓慢时,可能会使用查询分析器拨打电话并获取所选计划 - 并查看其外观。

如果是这样的话 - 在每次调用时放入一个opton来重新编译SP(重新编译)。

答案 1 :(得分:2)

参数嗅探google it。试试这个,它会将输入参数“重新映射”到局部变量,以防止SQL Server根据参数猜测查询计划:

ALTER PROCEDURE [dbo].[spGetPOIs]
    @lat1 float,
    @lon1 float,
    @lat2 float,
    @lon2 float,
    @minLOD tinyint, 
    @maxLOD tinyint,
    @exact bit
AS
BEGIN
DECLARE @X_lat1 float,
    @X_lon1 float,
    @X_lat2 float,
    @X_lon2 float,
    @X_minLOD tinyint, 
    @X_maxLOD tinyint,
    @X_exact bit



    -- Create the query rectangle as a polygon
    DECLARE @bounds geography;
    SET @bounds = dbo.fnGetRectangleGeographyFromLatLons(@X_lat1, @X_lon1, @lX_at2, @X_lon2);

    -- Perform the selection
    if (@exact = 0)
    BEGIN
        SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID]
        FROM [POIs]
        WHERE
            NOT ((@X_maxLOD  [MaxLOD])) AND
            (@bounds.Filter([Location]) = 1)
    END
    ELSE
    BEGIN
        SELECT [ID], [Name], [Type], [Data], [MinLOD], [MaxLOD], [Location].[Lat] AS [Latitude], [Location].[Long] AS [Longitude], [SourceID]
        FROM [POIs]
        WHERE
            NOT ((@X_maxLOD  [MaxLOD])) AND
            (@bounds.STIntersects([Location]) = 1)
    END

END

答案 2 :(得分:0)

我有一个类似的问题,它与索引有关 重建它们有助于SP再次快速运行。

我找到了解决方案here

https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url=https://google.com/&strategy=mobile&key=yourAPIKey