我有一个简单的索引视图。当我查询它时,它很慢。首先,我向您展示模式和索引。然后是简单的查询。最后是查询计划屏幕。
更新:本文底部的解决方案证明。
架构
这就是它的样子:-
CREATE view [dbo].[PostsCleanSubjectView] with SCHEMABINDING AS
SELECT PostId, PostTypeId,
[dbo].[ToUriCleanText]([Subject]) AS CleanedSubject
FROM [dbo].[Posts]
我的 udfToUriCleanText
只是用空字符替换各种字符。例如。用 '' 替换所有 '#' 字符。
然后我为此添加了两个索引:-
索引
主键索引(即聚集索引)
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
和非聚集索引
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
现在,它有大约 25K 行。没什么大不了的。
当我进行以下查询时,它们都需要大约 4 秒。怎么回事?这应该是..基本上是即时的!
查询 1
SELECT a.PostId
FROM PostsCleanSubjectView a
WHERE a.CleanedSubject = 'Just-out-of-town'
查询 2(添加了另一个 where 子句项)
SELECT a.PostId
FROM PostsCleanSubjectView a
WHERE a.CleanedSubject = 'Just-out-of-town' AND a.PostTypeId = 1
我做错了什么?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
所以,是的,有什么想法吗?
更新 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
更新 2:解决方案
是的,这是因为我没有在视图上使用索引,并且必须手动确保我没有展开视图。服务器为Sql Server 2008 标准版。完整答案如下。这是证据,WITH (NOEXPAND)
谢谢大家帮我解决这个问题:)