我怎样才能加快这个索引视图?

Pur*_*ome 12 sql t-sql sql-server indexed-view sql-server-2008

我有一个简单的索引视图.当我查询它时,它很慢.首先,我向您展示架构和索引.然后是简单的查询.最后一个查询计划screnie.

更新:本文底部的解决方案证明.

架构

这就是它的样子: -

CREATE view [dbo].[PostsCleanSubjectView] with SCHEMABINDING AS
    SELECT PostId, PostTypeId, 
        [dbo].[ToUriCleanText]([Subject]) AS CleanedSubject
    FROM [dbo].[Posts]
Run Code Online (Sandbox Code Playgroud)

我的udf ToUriCleanText只是用空字符替换各种字符.例如.用''替换所有'#'字符.

然后我在这上面添加了两个索引: -

索引

主键指数(即聚集指数)

CREATE UNIQUE CLUSTERED INDEX [PK_PostCleanSubjectView] ON 
    [dbo].[PostsCleanSubjectView] 
(
    [PostId] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
      SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF,
      ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

和非聚集索引

CREATE NONCLUSTERED INDEX [IX_PostCleanSubjectView_PostTypeId_Subject] ON 
    [dbo].[PostsCleanSubjectView] 
(
    [CleanedSubject] ASC,
    [PostTypeId] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
      SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF,
      ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

现在,它有大约25K行.什么都没有.

当我执行以下查询时,它们都需要大约4个奇秒.WTF?这应该......基本上是即时的!

查询1

SELECT a.PostId
FROM PostsCleanSubjectView a 
WHERE a.CleanedSubject = 'Just-out-of-town'
Run Code Online (Sandbox Code Playgroud)

查询2(添加了另一个where子句项)

SELECT a.PostId
FROM PostsCleanSubjectView a 
WHERE a.CleanedSubject = 'Just-out-of-town' AND a.PostTypeId = 1
Run Code Online (Sandbox Code Playgroud)

我做错了什么?UDF搞砸了吗?我想,因为我已经为这个视图编制了索引,所以它将被实现.因此,它不必计算该字符串列.

这是查询计划的一个屏幕,如果这有帮助: - 替代文字

另外,请注意它正在使用的索引?为什么使用该索引?

该指数是......

CREATE NONCLUSTERED INDEX [IX_Posts_PostTypeId_Subject] ON [dbo].[Posts] 
(
    [PostTypeId] ASC,
    [Subject] ASC
)
WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
      SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, 
      ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

所以,是的,任何想法的人?

更新1:添加了udf的架构.

CREATE FUNCTION [dbo].[ToUriCleanText]
(
    @Subject NVARCHAR(300)
)
RETURNS NVARCHAR(350) WITH SCHEMABINDING
AS 
BEGIN
   <snip>
   // Nothing insteresting in here. 
   //Just lots of SET @foo = REPLACE(@foo, '$', ''), etc.
END
Run Code Online (Sandbox Code Playgroud)

更新2:解决方案

是的,这是因为我没有在视图上使用索引,必须手动确保我没有展开视图.该服务器是Sql Server 2008标准版.完整的答案如下.这是证据,WITH (NOEXPAND) 替代文字

谢谢大家帮我解决这个问题:)

sis*_*sve 18

什么版本的SQL Server?我相信只有Enterprise和Developer Edition会自动使用索引视图,而其他人则使用查询提示来支持它.

SELECT a.PostId
FROM PostsCleanSubjectView a WITH (NOEXPAND)
WHERE a.CleanedSubject = 'Just-out-of-town' AND a.PostTypeId = 1
Run Code Online (Sandbox Code Playgroud)

MSDN上的查询提示(Transact SQL):

仅当在查询的SELECT部分​​中直接引用视图并且指定了WITH(NOEXPAND)或WITH(NOEXPAND,INDEX(index_value [,... n]))时,才会展开索引视图.

  • 我正在使用Sql Server标准版.好吧,让我试试吧...... ##### HOLY MOLLY.####即时!!!! 到底是怎么回事(NOEXPAND)呢?这就是我的预期!:) (2认同)