У меня есть простое индексированное представление. Когда я спрашиваю об этом, это довольно медленно. Сначала я покажу вам схемы и индексы. Тогда простые запросы. И наконец, план запроса.
Обновление: подтверждение решения в нижней части этого поста.
Схема
Вот как это выглядит: -
CREATE view [dbo].[PostsCleanSubjectView] with SCHEMABINDING AS
SELECT PostId, PostTypeId,
[dbo].[ToUriCleanText]([Subject]) AS CleanedSubject
FROM [dbo].[Posts]
Мой 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
И некластеризованный индекс
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
Теперь это около 25 тысяч строк. Ничего большого.
Когда я выполняю следующие запросы, они оба занимают около 4 с лишним секунд. WTF? Это должно быть .. в основном мгновенно!
Запрос 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 все испортил? Я думал, что, поскольку у меня есть index'd это представление, оно будет реализовано. Таким образом, ему не нужно будет вычислять этот строковый столбец.
Вот скриншот плана запроса, если это поможет: -

Кроме того, обратите внимание на индекс, который он использует? Почему он использует этот индекс?
Этот индекс ...
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 Standard Edition. Полный ответ ниже.
Вот доказательство, WITH (NOEXPAND)

Спасибо всем за помощь в решении этой проблемы:)