【问题标题】:Why is my view slow when I have indexed the columns?当我为列编制索引时,为什么我的视图变慢了?
【发布时间】:2011-05-06 18:08:45
【问题描述】:

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

【问题讨论】:

  • 查询计划说了什么?
  • 在我的脑海中,我看到 5 个不同的 JOIN 关键字条件,它们都与 OR 相关联。 SQL Server 正在检查这些条件中的每一个的每一行,您在其中一些条件中进行多次替换,并且您正在运行的 LIKE 比较无法使用索引,因为您使用的是 %xxx% 所以它可以出现在字段中的任何位置。除了视图上有索引之外,您的查询还存在潜在问题。您的源表中索引了哪些字段?
  • LIKE 和 REPLACE 很昂贵。 a FREETEXT search 可能会更好地为您服务,让数据库引擎处理 LIKEs
  • 当然,如果我向视图添加聚集索引,那么视图将被具体化为一个表,并且选择应该不受我使用带通配符和替换的 LIKE 的影响?跨度>

标签: sql-server performance indexing views


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 什么会导致索引过时?每当对基础数据进行插入、更新或删除操作时,SQL Server 数据库引擎肯定会自动维护索引吗?
    【解决方案3】:

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

    如果您真的需要这种搜索,您需要对您获得的速度感到满意,或者可能研究全文搜索。

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

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

    【讨论】:

    • 我相信@op 是在谈论索引视图和COUNT_BIG 上的索引,而不是基础表上的索引。
    猜你喜欢
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多