【问题标题】:SQL Server nonclustered indexesSQL Server 非聚集索引
【发布时间】:2012-10-01 05:28:27
【问题描述】:

我正在尝试找出在 SQL Server 中处理表索引的最佳方法。

我有一张只需要读取的表格。没有真正写入表(在初始设置之后)。

表中有大约 5-6 列需要索引。为整个表设置一个非聚集索引并将我需要索引的所有列添加到该索引中是否更有意义,或者我应该设置多个非聚集索引,每个索引都有一列?

我想知道哪种设置的读取性能更好。

在这方面的任何帮助都会很棒。

更新:

已经有一些很好的答案,但我想详细说明我的需求。

有一个带有自动记录的主表。我需要能够对超过 100 毫米的记录进行非常快速的计数。 where 语句会有所不同,但我试图索引 where 语句中所有可能的列。所以我会有这样的查询:

SELECT COUNT(recordID)
FROM tableName
WHERE zip IN (32801, 32802, 32803, 32809) 
AND makeID = '32' 
AND modelID IN (22, 332, 402, 504, 620)

或类似的东西:

SELECT COUNT(recordID)
FROM tableName
WHERE stateID = '9' 
AND classCode IN (3,5,9) 
AND makeID NOT IN (55, 56, 60, 80, 99)

因此,where 子句中可能有大约 5-6 列,但在哪些列上会有很大差异。

【问题讨论】:

  • 您需要提供更多信息,因为答案取决于您将运行的查询类型以及数据的样子,尤其是。基数。此外,您可能会受益于计算列、索引视图或全文索引。没有办法用你提供的最少信息说。
  • 谨慎选择clustered index 对读取性能也非常重要。

标签: sql-server indexing


【解决方案1】:

这取决于您的访问模式

对于只读表,我很可能会创建多个非聚集索引,每个索引都有多个键列来匹配 WHERE 子句,INCLUDEd 列用于非键列

我不会有一个非集群的全部,也没有一个每列:它们不会有用。实际查询

【讨论】:

    【解决方案2】:

    您拥有的索引越少 - 越好。每个索引可能会加快一些查询 - 但它也会产生开销并且需要维护。如果你不写太多东西到桌子上也不错。

    如果您可以将多个列组合成一个索引 - 完美!但是,如果您在多列上有一个复合索引,则只有在您使用/需要最左边的 n 列时才能使用该索引。

    因此,如果您在电话簿中的 (City, LastName, FirstName) 上有一个索引 - 如果您正在寻找,这很有效:

    • 给定城市的每个人
    • “波士顿”的每个“史密斯”
    • “纽约”的每一位“保罗·史密斯”

    但它不能用于在整个表格中查找名字为“Paul”的所有条目或姓氏为“Brown”的所有人;如果您还指定了City 列,则可以使用索引

    因此 - 复合索引是有益且可取的 - 但前提是您可以真正使用它们!如果您需要单独选择列,则只有一个包含 6 列的索引对您无济于事

    更新:使用具体查询,您现在可以开始设计哪些索引会有所帮助:

    SELECT COUNT(recordID)
    FROM tableName
    WHERE zip IN (32801, 32802, 32803, 32809) 
    AND modelID = '32' 
    AND model ID IN (22, 332, 402, 504, 620)
    

    在这里,(zip, modelID) 上的索引可能是个好主意 - zipmodelID 都用于 where 子句(一起),并且在索引中也有 recordID(作为Include(RecordID) 子句)也应该有所帮助。

    SELECT COUNT(recordID)
    FROM tableName
    WHERE stateID = '9' 
    AND classCode IN (3,5,9) 
    AND makeID NOT IN (55, 56, 60, 80, 99)
    

    再次:基于 WHERE 子句 - 在 (stateID, classCode, makeID) 上创建索引并可能添加 Include(RecordID) 以便非聚集索引成为覆盖(例如,您需要的所有信息查询位于非聚集索引本身 - 无需返回“基本”表)。

    【讨论】:

    • 感谢您的帮助。这是有道理的,但我不确定执行此操作的最佳方法,因为我在 WHERE 子句中处理多达 6 列。我有太多可能的组合来为每个组合创建一个索引。如果我只是将所有可能的列放在一个索引中,并且将 recordID 作为包含,那将是一个问题。它会减慢查询速度吗?
    • @Sequenzia:“只有一个包含所有列的索引”的想法将完全有益。如果幸运的话,您可能会在一种情况下获得正确的组合 - 在这种情况下,它将被使用 - 但在所有可能的列上都有一个索引IS NO是个好主意!不要这样做!最好没有索引而不是这样的索引!
    • 感谢您的跟进。我明白你在说什么。我做了更多的研究和一些测试。我知道这种方法在哪里行不通。我将尝试更多地确定我的查询需求并围绕它建立索引。感谢您的帮助。
    猜你喜欢
    • 2018-05-08
    • 2014-04-27
    • 2013-03-22
    • 2011-10-07
    • 1970-01-01
    • 2013-08-20
    • 2011-11-30
    • 2018-01-19
    相关资源
    最近更新 更多