Estou tentando entender o verdadeiro significado de Missing index para esta tabela específica quando já tenho índice nela e como resolvê-lo.
Tenho uma tabela muito usada e tem aproximadamente 2,5GB. Como é muito usado, um pouco hesitante em criar índices que não são muito necessários (discutível). Esta tabela foi heap anteriormente, recentemente ela é alterada para tabela após alterar a chave primária para clusterizada de não clusterizada.
Quando executo sp_blitzindex com o nome do banco de dados ou com esta tabela, dá resultado como abaixo:
Principalmente sugere criar índice na coluna APT_ID e incluir sugere LOGID, RECEIVE_TIME e algumas outras colunas. Se olharmos para a definição da tabela, a chave primária é definida em LOGID e RECEIVE_TIME. E também temos um índice NC na coluna APT_ID.
A tabela DDL é a seguinte:
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
O índice NC nesta tabela é:
CREATE NONCLUSTERED INDEX [IDX_TXN_LOG_1] ON [dbo].[TXN_LOG]
(
[APT_ID] ASC
)
INCLUDE([RECEIVE_TIME])
GO
O uso atual do índice não parece oferecer suporte ao índice NC, pois a gravação é maior que a contagem de leitura.
Sinceras desculpas por anexar imagens na pergunta. Agradeço se eu puder obter alguns conselhos de especialistas sobre isso. Desde já, obrigado.
Versão: Microsoft SQL Server 2014 (SP3-GDR) (KB4532095) - 12.0.6118.4 (X64) 12 de dezembro de 2019 21:46:15 Copyright (c) Microsoft Corporation Enterprise Edition: licenciamento baseado em núcleo (64 bits) no Windows NT 6.3 (Build 9600: ) (Hipervisor)
Para limpar e simplificar um pouco sua pergunta:
Esse é realmente um índice diferente do que você já tem.
Vamos pegar o velho exemplo da lista telefônica. As páginas brancas da lista telefônica estavam em LAST_NAME, FIRST_NAME, MIDDLE_NAME. Isso é ótimo se você executar uma consulta como esta:
Mas se você não souber o sobrenome de alguém e perguntar por isso:
Então você vai escanear a lista telefônica inteira procurando por mim. A primeira coluna do índice é incrivelmente importante. É por isso que o SQL Server está pedindo um índice em APT_ID, além de outras colunas incluídas.
Então você pode perguntar: "Por que um índice existente em APT_ID sozinho não é suficiente?" O problema é que, no seu caso, o APT_ID não é seletivo o suficiente ou as pessoas estão solicitando intervalos de APT_IDs. O SQL Server está tendo que fazer várias pesquisas de chave e as recomendações de índice ausentes estão tentando removê-las.
Impossível dizer qualquer coisa, já que o índice ausente é estúpido.
Por um lado, não leva em conta a seletividade. Ter um índice que não cobre a consulta é bom se você retornar apenas algumas linhas. Mas o MI não se preocupa com a seletividade, então quer cobrir todas as consultas. E pode sugerir um índice em (a) incluindo (b,c), e outro índice em (a) incluindo (b,c,d). Ou seja, sem esperteza (que vem do fato de não querer gastar muito tempo na hora de gerar essas recomendações).
Você cria índices para dar suporte às suas consultas.
Ative o armazenamento de consultas e trabalhe a partir daí.
Ou crie índices e depois de um tempo veja se eles foram usados.
Ou, se você conhece a carga da consulta, trabalhe com as consultas.
Talvez eu tenha perdido algum ponto-chave no seu post, então por favor me avise. :-)