Esta pergunta é sobre o desempenho do índice do SQL Server com a varchar(2000)
como INCLUDE
em um índice de cobertura.
Estou tentando melhorar o desempenho em um aplicativo de banco de dados lento e instável. Em alguns casos, os dados são acessados através de grandes cadeias de varchar, com as consultas, incluindo operações de cadeia multple como SUBSTRING()
, SPACE()
, e DATALENGTH()
. Aqui está um exemplo simplificado de acesso;
update fattable set col3 =
SUBSTRING(col3,1,10) + '*' +
SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2
O esquema fica assim:
CREATE TABLE [dbo].[FatTable](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[col1] [nchar](12) NOT NULL,
[col2] [int] NOT NULL,
[col3] [varchar](2000) NOT NULL, ...
O índice a seguir foi definido, com um campo de cobertura na coluna de texto grande.
CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable] ( [col2] ASC )
INCLUDE( [col3] )
Pelo que li, é ruim colocar grandes campos de dados em um índice. Eu tenho lido vários artigos, incluindo http://msdn.microsoft.com/en-us/library/ms190806.aspx, que discutem o impacto da paginação e do tamanho do disco no desempenho do índice. Dito isto, o plano de consulta definitivamente usa o índice de cobertura. Não tenho informações suficientes para determinar quanto isso realmente está me custando em termos de carga do sistema. Sei que, no geral, o sistema está com um desempenho ruim e estou preocupado que esse seja um dos problemas. Questões:
Colocar essa
varchar(2000)
coluna no índice éINCLUDE
sempre uma boa idéia?Como os
INCLUDE
campos são armazenados em nós folha, eles têm muito desempenho no índice de impacto?
Atualização: Obrigado pelas excelentes respostas! Essa é uma pergunta injusta, de certa forma - como vocês dizem, não há resposta certa absoluta sem estatísticas e perfis reais. Como tantos problemas de desempenho, acho que a resposta é "depende".
fonte
VARCHAR(2000)
que normalmente armazena apenas dez caracteres é uma coisa; 2.000 bytes sólidos por registro é outra coisa.Respostas:
Ever é uma palavra grande, mas, em geral, não, eu não colocaria um campo varchar (2000) em um INCLUDE.
E sim, a maneira como os dados são armazenados no nível da página pode afetar seriamente o desempenho do índice, dependendo de como o índice é usado.
O problema é que, quanto mais linhas de dados você puder agrupar em uma página, menos páginas precisarão ser acessadas, mais rápido será o seu sistema, na maior parte. Adicionar uma coluna realmente grande significa menos informações armazenadas em uma página; portanto, no caso de buscas ou varreduras no intervalo, mais páginas precisam ser lidas para recuperar os dados, reduzindo a velocidade das coisas.
Para saber com certeza se esse é um problema na sua consulta ou no seu sistema, você precisa monitorar as leituras, especialmente o número de páginas que a consulta usa.
fonte
Você pode revisar a chave de índice em cluster atual e, talvez, criar
col2
a chave de índice em cluster? Dessa forma, você obtém o comportamento de 'incluir' de cobertura (já que os índices agrupados são sempre 'incluindo' tudo) sem duplicar os dados. Isso, é claro, está sujeito a muitosif
ebut
, no entanto, talvez valha a pena considerar. Obviamente, se o índice clusterizado atual estiver aplicando uma restrição (chave primária, exclusiva), a restrição deverá ser movida para um índice não clusterizado.fonte
É difícil responder. Tudo dependerá da sua taxa de leitura: gravação. Você testou uma carga de trabalho ou simulou um ciclo de negócios inteiro em um sistema de teste, com e sem a coluna incluída? A pesquisa sem ele pode custar muito, mas se você estiver atualizando os dados com mais frequência do que os lendo, isso pode ser bom.
fonte
VARCHAR(2000)
coluna ou você está solucionando problemas de desempenho de uma consulta muito específica que não representa a maioria das consultas? Como Grant sugere, se essa coluna não for usada em muitas consultas ou realmente causar problemas nas buscas, provavelmente será melhor pagar o preço pela pesquisa quando você precisar, mas não pagar pelo armazenamento quando não precisar. . Novamente, é realmente difícil dizer em que lado da cerca você deve estar, já que realmente não temos detalhes específicos (e ainda mais difícil porque você não pode testar - você deve se esforçar para consertar isso).Sei que estou atrasado para esta festa, mas indexaria exatamente as expressões usadas para localizar linhas, como substring (col3,10,1). Se todo o col3 for usado, eu indexaria CHECKSUM (col3) (entendendo que pode haver colisões, é claro).
fonte