当我已经有索引以及如何解决它时,我试图理解这个特定表的缺失索引的真正含义。
我有一张经常使用的桌子,大约 2.5GB。由于它被大量使用,有点犹豫要创建不是非常需要的索引(值得商榷)。该表之前是堆的,最近将主键从非集群更改为集群后更改为表。
当我使用数据库名称或此表运行 sp_blitzindex 时,结果如下:
大多数情况下,它建议在 APT_ID 列上创建索引,并包括建议 LOGID、RECEIVE_TIME 和其他一些列。如果我们看表定义,主键定义在 LOGID 和 RECEIVE_TIME。而且我们在 APT_ID 列上有一个 NC 索引。
表 DDL 如下:
CREATE TABLE [dbo].[TXN_LOG](
[LOGID] [int] IDENTITY(1,1) NOT NULL,
[RECEIVE_TIME] [varchar](15) NOT NULL,
[APT_ID] [int] NOT NULL,
[VAR32_01] [varchar](32) NULL,
[VAR32_02] [varchar](32) NULL,
.
.
.
[ERROR_CODE] [varchar](20) NULL,
[MESSAGE_ID] [varchar](40) NULL,
[END_POINT_ID] [varchar](50) NULL,
[NODE_ID] [varchar](40) NULL,
[TIMEOUT_NETWORK_ID] [int] NULL,
[TXN_SUMMARY] [numeric](1, 0) NULL,
[D_FLAG] [numeric](1, 0) NULL,
CONSTRAINT [PKTXN_LOG] PRIMARY KEY CLUSTERED
(
[LOGID] ASC,
[RECEIVE_TIME] ASC
))
GO
此表上的 NC 索引为:
CREATE NONCLUSTERED INDEX [IDX_TXN_LOG_1] ON [dbo].[TXN_LOG]
(
[APT_ID] ASC
)
INCLUDE([RECEIVE_TIME])
GO
当前使用的索引似乎不支持 NC 索引,因为写入次数高于读取次数。
对于在问题中附加图像表示诚挚的歉意。感谢我能否就此获得一些专家建议。提前致谢。
版本:Microsoft SQL Server 2014 (SP3-GDR) (KB4532095) - 12.0.6118.4 (X64) 2019 年 12 月 12 日 21:46:15 版权所有 (c) Microsoft Corporation Enterprise Edition:Windows NT 上基于内核的许可(64 位) 6.3(内部版本 9600:)(管理程序)
要清理和简化您的问题:
这确实是一个与您已有的不同的索引。
让我们以电话簿的旧示例为例。电话簿的白页位于 LAST_NAME、FIRST_NAME、MIDDLE_NAME。如果您运行这样的查询,那就太好了:
但是,如果您不知道某人的姓氏,并且您要求这样做:
然后你会扫描整个电话簿来寻找我。索引中的第一列非常重要。这就是 SQL Server 要求 APT_ID 以及其他列的索引的原因。
所以您可能会问,“为什么仅 APT_ID 上的现有索引还不够?” 问题是,在您的情况下,APT_ID 的选择性不够,或者人们要求 APT_ID 的范围。SQL Server 必须进行大量的键查找,而缺少的索引建议正试图删除这些。
不可能说什么,因为缺少索引是愚蠢的。
一方面,它没有考虑选择性。如果您只返回几行,那么拥有一个不涵盖查询的索引就可以了。但 MI 并不关心选择性,因此它希望涵盖每个查询。它可以建议(a)上的一个索引,包括(b,c),以及(a)上的另一个索引,包括(b,c,d)。即,没有智能(这是因为它不想在生成这些推荐时花费太多时间)。
您创建索引来支持您的查询。
打开查询存储并从那里开始工作。
或者创建索引并在一段时间后查看它们是否被使用。
或者,如果您知道查询负载,则使用查询。
也许我错过了您帖子中的一些关键点,请告诉我。:-)