Почему мое представление медленно отображается, когда я проиндексировал столбцы?

В SQL Server я поместил кластеризованный индекс в представление, чтобы устранить неэффективность объединения с помощью операторов LIKE:

   CREATE VIEW KeywordCount WITH SCHEMABINDING
    AS
    SELECT 
        K.ID AS KeywordID
        ,COUNT_BIG(*) AS KeywordCount
    FROM dbo.Grants G
    INNER JOIN dbo.GrantStatuses GS2 ON GS2.ID = G.StatusID AND GS2.Status NOT IN ('Pre-Submission', 'Awaiting Signatory Approval', 'Modifying', 'Closed')
    INNER JOIN dbo.Keywords K
        ON G.Keywords LIKE '%' + K.Word + '%'                                           --It's one of the grant's keywords
        OR G.Title LIKE '%' + K.Word + '%'                                              --Word appears in the title
        OR Replace(G.Title, '-', ' ') LIKE '%' + Replace(K.Word, '-', ' ') + '%'        --Word with hyphens replaced appears in the title
        OR G.Synopsis LIKE '%' + K.Word  + '%'                                          --Word appears in the Synopsis
        OR Replace(G.Synopsis, '-', ' ') LIKE '%' + Replace(K.Word, '-', ' ')+ '%'      --Word with hyphens replaced appears in the synopsis
    GROUP BY K.ID
    GO

    CREATE UNIQUE CLUSTERED INDEX IX_KeywordCount 
        ON dbo.KeywordCount (KeywordID)
    GO

Затем я добавил еще один индекс в столбец KeywordCount:

    CREATE INDEX IX_KeywordCount_Count 
        ON dbo.KeywordCount (KeywordCount)
    GO

Так почему следующий запрос занимает 7 минут? Разве индекс не должен дать мне намного лучшую производительность?

    SELECT TOP 10 * FROM KeywordCount ORDER BY KeywordCount DESC

РЕДАКТИРОВАТЬ Спасибо всем, но я знаю, что LIKE заявления и REPLACE сделает эту точку зрения неэффективной. Вот почему я добавил кластерный индекс. Я думал, что размещение кластеризованного индекса в представлении материализует данные в таблицу, чтобы база данных не выполняла объединения. План запроса действительно говорит, что он выполняет объединения. Это почему?

3 ответа

Решение

Я нашел решение в этой статье: http://technet.microsoft.com/en-us/library/cc917715.aspx

SELECT TOP 10 * FROM KeywordCount WITH (NOEXPAND) ORDER BY KeywordCount DESC

По какой-то причине план запроса не использовал индекс, но я добавил подсказку WITH (NOEXPAND), и мой запрос был выполнен мгновенно - большое спасибо Quassnoi за то, что он указал, что нужно сделать.

Обратите внимание, что WITH (NOEXPAND) означает, что представление должно смотреть только на индексы, а не на данные таблицы. Это означает, что если индексы не обновлены, представление также не будет.

LIKE '%' + Replace(K.Word, '-', ' ') + '%' (% подстановочные знаки в начале поисковых терминов) НИКОГДА не смогут использовать любые индексы. Если вы используете такое утверждение, не удивляйтесь, что у вас будет полное сканирование таблицы все время.

Если вы действительно нуждаетесь в таком поиске, вам нужно либо справиться со скоростью, с которой вы работаете, либо исследовать полнотекстовый поиск.

Другой вариант - изменить ваши операторы LIKE на: LIKE K.Word + '%'

Если вы используете % Подстановочный знак только в конце, SQL Server имеет шанс на самом деле использовать индекс на K.Word и, таким образом, ускорить поиск.

Другие вопросы по тегам