相关疑难解决方法(0)

优化包含窗口函数的参数化T-SQL查询的执行计划

编辑:我已经更新了示例代码并提供了完整的表和视图实现以供参考,但基本问题仍未改变.

我在数据库中有一个相当复杂的视图,我试图查询.当我尝试通过将WHERE子句硬编码为特定外键值从视图中检索一组行时,视图执行速度非常快,并且具有最佳执行计划(正确使用索引等)

SELECT * 
FROM dbo.ViewOnBaseTable
WHERE ForeignKeyCol = 20
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试向查询添加参数时,我的执行计划突然崩溃了.当我运行下面的查询时,我正在获取索引扫描而不是遍布整个地方并且查询性能非常差.

DECLARE @ForeignKeyCol int = 20

SELECT * 
FROM dbo.ViewOnBaseTable
WHERE ForeignKeyCol = @ForeignKeyCol 
Run Code Online (Sandbox Code Playgroud)

我正在使用SQL Server 2008 R2.什么给这里?使用导致次优计划的参数有什么用?任何帮助将不胜感激.

作为参考,这里是我得到错误的对象定义.

CREATE TABLE [dbo].[BaseTable]
(
    [PrimaryKeyCol] [uniqueidentifier] PRIMARY KEY,
    [ForeignKeyCol] [int] NULL,
    [DataCol] [binary](1000) NOT NULL
)

CREATE NONCLUSTERED INDEX [IX_BaseTable_ForeignKeyCol] ON [dbo].[BaseTable]
(
    [ForeignKeyCol] ASC
)

CREATE VIEW [dbo].[ViewOnBaseTable]
AS
SELECT
    PrimaryKeyCol,
    ForeignKeyCol,
    DENSE_RANK() OVER (PARTITION BY ForeignKeyCol ORDER BY PrimaryKeyCol) AS ForeignKeyRank,
    DataCol
FROM
    dbo.BaseTable
Run Code Online (Sandbox Code Playgroud)

我确定窗口函数是问题,但我通过窗口函数分区的单个值过滤我的查询,所以我希望优化器先过滤然后运行窗口函数.它在硬编码示例中执行此操作,但不是参数化示例.以下是两个查询计划.最佳计划是好的,底层计划是坏的.

查询执行计划

t-sql sql-server query-optimization sql-server-2008-r2

20
推荐指数
1
解决办法
6451
查看次数