编辑:我已经更新了示例代码并提供了完整的表和视图实现以供参考,但基本问题仍未改变.
我在数据库中有一个相当复杂的视图,我试图查询.当我尝试通过将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)
我确定窗口函数是问题,但我通过窗口函数分区的单个值过滤我的查询,所以我希望优化器先过滤然后运行窗口函数.它在硬编码示例中执行此操作,但不是参数化示例.以下是两个查询计划.最佳计划是好的,底层计划是坏的.
