Estou ajustando alguns índices e vendo alguns problemas que gostaria de seguir seu conselho
Em uma tabela existem 3 índices
dbo.Address.IX_Address_ProfileId
[1 KEY] ProfileId {int 4}
Reads: 0 Writes:10,519
dbo.Address.IX_Address
[2 KEYS] ProfileId {int 4}, InstanceId {int 4}
Reads: 0 Writes:10,523
dbo.Address.IX_Address_profile_instance_addresstype
[3 KEYS] ProfileId {int 4}, InstanceId {int 4}, AddressType {int 4}
Reads: 149677 (53,247 seek) Writes:10,523
1- Preciso mesmo dos 2 primeiros índices ou devo descartá-los?
2- existem consultas em execução que usam a condição em que profileid = xxxx e outras usam em que profileid = xxxx e InstanceID = xxxxxx. Por que o otimizador escolhe o terceiro índice e não o 1º ou o 2º?
Também estou executando uma consulta que recebe a espera de bloqueio em cada índice. Se estou recebendo essas contagens, o que devo fazer para ajustar esse índice?
Row lock waits: 484; total duration: 59 minutes; avg duration: 7 seconds;
Page lock waits: 5; total duration: 11 seconds; avg duration: 2 seconds;
Lock escalation attempts: 36,949; Actual Escalations: 0.
estrutura da tabela é
TABLE [dbo].[Address](
[Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[AddressType] [int] NULL,
[isPreferredAddress] [bit] NULL,
[StreetAddress1] [nvarchar](255) NULL,
[StreetAddress2] [nvarchar](255) NULL,
[City] [nvarchar](50) NULL,
[State_Id] [int] NOT NULL,
[Zip] [varchar](20) NULL,
[Country_Id] [int] NOT NULL,
[CurrentUntil] [date] NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[ProfileId] [int] NOT NULL,
[InstanceId] [int] NOT NULL,
[County_id] [int] NULL,
CONSTRAINT [PK__Address__3214EC075E4BE276] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
este é um exemplo (essa consulta criada pelo hibernate parece estranha)
(@P0 bigint)select addresses0_.ProfileId as Profile15_109_1_
, addresses0_.Id as Id1_20_1_
, addresses0_.Id as Id1_20_0_
, addresses0_.AddressType as AddressT2_20_0_
, addresses0_.City as City3_20_0_
, addresses0_.Country_Id as Country_4_20_0_
, addresses0_.County_id as County_i5_20_0_
, addresses0_.CreatedDate as CreatedD6_20_0_
, addresses0_.CurrentUntil as CurrentU7_20_0_
, addresses0_.InstanceId as Instance8_20_0_
, addresses0_.isPreferredAddress as isPrefer9_20_0_
, addresses0_.ProfileId as Profile15_20_0_
, addresses0_.State_Id as State_I10_20_0_
, addresses0_.StreetAddress1 as StreetA11_20_0_
, addresses0_.StreetAddress2 as StreetA12_20_0_
, addresses0_.UpdatedDate as Updated13_20_0_
, addresses0_.Zip as Zip14_20_0_
from dbo.Address addresses0_
where addresses0_.ProfileId=@P0
(@P0 bigint,@P1 bigint)
select addressdmo0_.Id as Id1_20_
, addressdmo0_.AddressType as AddressT2_20_
, addressdmo0_.City as City3_20_
, addressdmo0_.Country_Id as Country_4_20_
, addressdmo0_.County_id as County_i5_20_
, addressdmo0_.CreatedDate as CreatedD6_20_
, addressdmo0_.CurrentUntil as CurrentU7_20_
, addressdmo0_.InstanceId as Instance8_20_
, addressdmo0_.isPreferredAddress as isPrefer9_20_
, addressdmo0_.ProfileId as Profile15_20_
, addressdmo0_.State_Id as State_I10_20_
, addressdmo0_.StreetAddress1 as StreetA11_20_
, addressdmo0_.StreetAddress2 as StreetA12_20_
, addressdmo0_.UpdatedDate as Updated13_20_
, addressdmo0_.Zip as Zip14_20_
from dbo.Address addressdmo0_
left outer join dbo.Profile profiledmo1_
on addressdmo0_.ProfileId=profiledmo1_.Id
where profiledmo1_.Id=@P0 and addressdmo0_.InstanceId=@P1
sql-server
index
index-tuning
sebeid
fonte
fonte
Respostas:
Resposta à pergunta 1:
Pelo que você postou, você pode descartar os dois primeiros índices, pois o terceiro cobrirá todas as consultas mencionadas e o otimizador de consultas também o vê quando cria o plano de consulta (com base no plano que você postou).
Resposta à pergunta 2:
Ele está sempre usando o terceiro índice, porque já tem mais dados no índice com as duas chaves de índice adicionais (
InstanceId and AddressType
). Isso evita que o SQL precise extrair InstanceId e AddressType da chave primária (a parte de pesquisa de chave do plano de execução) para satisfazer a consulta.O que eu sugeriria é soltar os dois primeiros índices e reconstruir o terceiro com colunas de inclusão para cobrir as outras colunas que estão sendo solicitadas na consulta
Isso deve ajudar nas consultas e remover a pesquisa de chave do plano de consulta.
Veja se os bloqueios caem após essas alterações e se não o fizermos, podemos nos aprofundar um pouco mais.
fonte
Não é a pergunta declarada, mas pode obter melhores planos de consulta com melhores consultas
Você está matando a parte externa esquerda com o local
onde profiledmo1_.Id=@P0 transforma isso em uma junção
Nos índices, apenas os dois primeiros
tudo o que a associação faz é garantir que ele esteja no perfil, mas você não está relatando nada do perfil
e como isso não acontece?
fonte
Parece que você pode descartar o índice 1 e 2, pois o índice 3 inclui todas as informações (colunas) necessárias. Pode ser possível que outro índice faça sentido como índice clusterizado para representar a chave primária.
Com esta informação limitada, podemos apenas adivinhar. Se você precisar de mais dicas, publique informações mais detalhadas como sua estrutura de tabela completa (tabelas, índice, chaves, ...), suas consultas e o plano de execução.
fonte