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?这应该......基本上是即时的!
SELECT a.PostId
FROM PostsCleanSubjectView a
WHERE a.CleanedSubject = 'Just-out-of-town'
Run Code Online (Sandbox Code Playgroud)
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)
所以,是的,任何想法的人?
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)
是的,这是因为我没有在视图上使用索引,必须手动确保我没有展开视图.该服务器是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)
仅当在查询的SELECT部分中直接引用视图并且指定了WITH(NOEXPAND)或WITH(NOEXPAND,INDEX(index_value [,... n]))时,才会展开索引视图.