1

我有一个相当复杂的视图,它的定义中有大约 100 个子查询。

简单的语句如:

SELECT * FROM MyView

生成计划并执行查询需要 2 秒。当计划被缓存时,后续选择需要不到 1ms 的时间来执行。

如果我只有几个查询,这种情况会很好 - 性能只有一次是可以接受的。问题是我们的 ORM 使用 CTE 生成带有参数的分页查询。更改参数值(页面)会导致查询计划重新计算 - 在这种情况下,不幸的是这需要大约 4 秒!

让我们添加过滤、排序,你就会知道会发生什么。

我可以做些什么来减少查询计划的创建时间或减少它们或以任何其他方式优化它?

@MartinSmith“除非文本以某种方式更改,否则 SQL Server 不会为每个参数值生成计划”

我有一个这样的查询(我在这里放了星星而不是 120 多个字段列表):

DECLARE @low int = 20;
DECLARE @high int = 300;

WITH __actualSet
AS (
SELECT *
    ,ROW_NUMBER() OVER (
        ORDER BY CURRENT_TIMESTAMP
        ) AS __rowcnt
FROM (
    SELECT TOP 5000 *
    FROM [dbo].[Project] [LPA_L1]
    ORDER BY [LPA_L1].[CreatedOn] ASC
    ) AS _tmpSet
)
SELECT *
FROM __actualSet
WHERE [__rowcnt] > @low
AND [__rowcnt] <= @high
ORDER BY [__rowcnt] ASC

我第一次运行这个查询〜4s。第二次~1ms。当我更改参数值时 - 再次 4s。也许我在这里误解了一些东西?

4

1 回答 1

1

要在 SSMS 中测试并为不同的值重用相同的计划,您需要参数化查询并执行它sp_executesql

DECLARE @low int = 20;
DECLARE @high int = 300;

EXEC sp_executesql N'
WITH __actualSet
AS (
SELECT *
    ,ROW_NUMBER() OVER (
        ORDER BY CURRENT_TIMESTAMP
        ) AS __rowcnt
FROM (
    SELECT TOP 5000 *
    FROM [dbo].[Project] [LPA_L1]
    ORDER BY [LPA_L1].[CreatedOn] ASC
    ) AS _tmpSet
)
SELECT *
FROM __actualSet
WHERE [__rowcnt] > @low
AND [__rowcnt] <= @high
ORDER BY [__rowcnt] ASC

', N'@low INT, @high INT', @low = @low, @high = @high
于 2013-06-10T12:48:24.133 回答