当我对列建立索引后,为什么我的视图速度很慢?

发布于 2024-10-01 22:08:06 字数 1689 浏览 3 评论 0原文

在 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 会使此视图效率低下。这就是我添加聚集索引的原因。我认为将聚集索引放在视图上会将数据具体化到表中,以便数据库不必执行连接。查询计划确实表明它正在执行连接。这是为什么?

In SQL Server I have put a clustered index on a view to eliminate the inefficiency of a join using LIKE statements:

   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

Then I added another index on the KeywordCount column:

    CREATE INDEX IX_KeywordCount_Count 
        ON dbo.KeywordCount (KeywordCount)
    GO

So why does the following query take 7 minutes to run? Shouldn't the index give me much better performance?

    SELECT TOP 10 * FROM KeywordCount ORDER BY KeywordCount DESC

EDIT
Thanks everyone, but I know that LIKE statements and REPLACE will make this view inefficient. That's why I added the clustered index. I thought that putting a clustered index onto the view would materialize the data into a table so that the database would not have to do the joins. The query plan does say that it is doing the joins. Why is that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦途 2024-10-08 22:08:06

我在这篇文章中找到了解决方案: http://technet.microsoft.com/en -us/library/cc917715.aspx

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

由于某种原因,查询计划没有使用索引,但我添加了 WITH (NOEXPAND) 提示,我的查询立即运行 - 非常感谢Quassnoi 指出了正确的做法。

I found the solution in this article: http://technet.microsoft.com/en-us/library/cc917715.aspx

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

For some reason the query plan wasn't using the index, but I added the WITH (NOEXPAND) hint and my query ran instantly - many thanks to Quassnoi for pointing out the correct thing to do.

始于初秋 2024-10-08 22:08:06

请注意,WITH (NOEXPAND) 意味着视图应该只查看索引,而不是表数据。这意味着如果索引不是最新的,视图也不会是最新的。

Please note that WITH (NOEXPAND) means that the view should only look at the indexes, and not the table data. That means if the indexes are not up to date the view will not be either.

黑寡妇 2024-10-08 22:08:06

LIKE '%' + Replace(K.Word, '-', ' ') + '%' (搜索词开头的 % 通配符)将 < strong>永远不能使用任何索引。如果您使用这种语句,那么您将一直进行全表扫描,请不要感到惊讶。

如果您确实需要这种搜索,则需要对所获得的速度感到满意,或者研究全文搜索。

另一种选择是将 LIKE 语句更改为:LIKE K.Word + '%'

如果仅在末尾使用 % 通配符,SQL Server 有机会实际使用 K.Word 上的索引,从而加快查找速度。

A LIKE '%' + Replace(K.Word, '-', ' ') + '%' (% wildcards at the beginning of the search terms) will NEVER be able to use any indices. If you use that kind of statement, don't be surprised you'll have full table scans all the time.

If you really need that kind of searching, you need to either be okay with the speed you're getting, or maybe investigate full-text searching.

The other option would be to change your LIKE statements to: LIKE K.Word + '%'

If you use the % wildcard only at the end, SQL Server stands a chance to actually use an index on K.Word and thus speed up the lookup.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文