Sql 了解SSMS中的索引和缺少的索引建议

Sql 了解SSMS中的索引和缺少的索引建议,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,了解索引和缺少的索引建议 我试图更好地理解索引。我有很多阅读要做,并且从其他SO帖子中找到了许多有价值的资源,其中一些我已经阅读过,其他我仍然需要阅读。同时,我正在努力提高数据库的性能 我已经了解到覆盖索引的性能将比单个列上的索引更好,因此我决定从删除单个索引开始,让建议的查询执行计划推荐索引 SSMS索引建议 CREATE NONCLUSTERED INDEX IX_my_index_name ON [dbo].[my_table] ([field_a],[field_b]) INCLUDE

了解索引和缺少的索引建议

我试图更好地理解索引。我有很多阅读要做,并且从其他SO帖子中找到了许多有价值的资源,其中一些我已经阅读过,其他我仍然需要阅读。同时,我正在努力提高数据库的性能

我已经了解到覆盖索引的性能将比单个列上的索引更好,因此我决定从删除单个索引开始,让建议的查询执行计划推荐索引

SSMS索引建议

CREATE NONCLUSTERED INDEX IX_my_index_name
ON [dbo].[my_table] ([field_a],[field_b])
INCLUDE (
   [field_1]
  ,[field_2]
  ,[field_3]
  ,[field_4]
  ,[field_5]
  ,[field_6]
)
表格详细信息

字段1-6是我常用于连接正在使用的两个表的列。字段a和b位于我运行的几个耗时查询的where子句中

我理解使用字段1-6,因为大部分字段都包含许多不同的值,但是
字段a
只有大约75个不同的值,而
字段b
只有3个不同的值。这是一个有70MM记录的表格

请注意,这是一个堆。此表上的所有记录都来自另一个具有主键的表,因此它附带唯一值,但它未设置为此表上的键或唯一索引。SSMS不建议将该列包含在此索引中。想知道我应该如何处理这个表中的唯一值吗?我猜是一个聚集的、唯一的索引

我的问题

  • 我想了解这个索引建议背后的逻辑。鉴于a列和b列中类似值的相关信息,为什么建议这样做

  • 我想了解
    ON
    列和
    INCLUDE
    列之间的区别


  • 索引中的ON列可用于搜索行。这些字段包含在索引树中。一旦找到行,如果需要任何其他列,例如select part或JOIN中的字段,则必须从表中提取这些行。这在执行计划中称为
    键查找

    如果索引有多个列,并且where子句中没有指定所有列,则只要给定字段,就可以从第一个开始使用这些列。例如,索引有字段A、B、C、D,where子句有字段A、B和D,那么只有A和B可以用来获取数据

    如果表具有聚集索引,则聚集索引中键的值存储在其他索引中,并用于从表本身查找行。如果没有聚集索引,则以类似的方式使用RID(行ID)从表中查找行

    索引中的include列是附加列,它们的数据存储在非聚集索引的叶级。通过这种方式,SQLServer可以直接从表中读取数据,并跳过整个表的读取过程。这称为
    覆盖索引

    包含索引(或覆盖索引)允许SQL Server在索引本身中查找满足查询所需的所有信息,而无需返回到实际的数据页以获取请求的信息。它是数据的副本,但包含部分中的列不用于搜索-仅用于返回数据。您的表应该始终(除非在非常非常特殊的情况下,例如在执行大量插入时)具有聚集索引


    使用索引的原因是为了减少SQL Server必须读取整个表才能返回数据的扫描次数。通过使用索引,SQL Server可以只查找和读取返回您请求的行所需的页面。如果列的值数量有限,SQL Server可能会决定忽略索引并进行扫描。您必须查看生成的查询计划,以查看SQL Server是否使用该索引。如果SQL Server建议索引,则通常意味着SQL Server引擎将使用该索引。但是每个索引都有成本——需要维护,所以不要创建太多索引。

    我想了解这个索引建议背后的逻辑。鉴于字段a和b中类似值的相关信息,为什么建议这样做?

    tl;dr这完全取决于您如何查询数据

    这是一个很难回答的问题,因为它取决于您查询表的频率、查询类型、服务器负载以及其他一系列内容

    例如,如果您在许多用“简单计划”运行的查询中使用字段1-6,那么SQLServer就不会认为它们是索引的好的CANDITE。“简单计划”或“琐碎计划”是SQL SERVER为其认为不足以生成完整计划的查询提供的计划

    SQL SERVER将对长时间运行的查询进行“全面研究”。将计算并存储这些历史图。这将提醒SQL SERVER现有索引不足。“充分探索”计划是指SQL SERVER已扩展并为其生成非简单查询计划的计划


    我想了解ON列和INCLUDE列之间的区别?

    On和Include之间的区别是

    On语句将在索引中包含该列。这意味着存储时列是索引的一部分

    所以索引是这样工作的。表的索引形成一个B树。B-树中的节点包含聚类索引值,以及其余值的ROWID。如果在B-树中搜索一个不属于聚类索引的值,它将首先找到聚类索引,然后它将有一个用于其余数据的内存地址。然后,它将再次查找该内存地址中的其他值

    INCLUDE子句添加最低/leaf级别的数据,而不是t
    SELECT field1, field2, field3
    FROM   table1
    WHERE  field4 = 1 AND field5 = 'bob'