Tenho uma situação em que o SQL Server está dando erro de tamanho de índice superior a 900 bytes. Está acontecendo porque uma das colunas na definição do índice é varchar (2000) e sempre que seu comprimento ultrapassa 800, ocorre o erro.
Então, minha pergunta é: existe alguma maneira de dizer na definição do índice para incluir apenas os primeiros 800 caracteres da coluna?
Algumas pessoas em blogs sugeriram adicionar uma coluna adicional à tabela que terá os primeiros 800 caracteres de outra coluna e adicionar indexação nesta nova coluna adicional em vez da coluna original. Mas acho que isso afetará o desempenho geral porque as consultas de leitura ainda estão sendo feitas na coluna original.
Por favor, sugira se há alguma outra maneira de resolver este problema.
Escrevi um post sobre esse tipo de situação aqui , que é mais aprofundado do que esta resposta.
Isso pode ser feito criando uma coluna computada como
LEFT(MyColumn, 800)
e, em seguida, indexando essa coluna. Observe que a coluna não precisa ser materializada na tabela usando aPERSISTED
cláusula -- a criação de um índice na coluna materializará os valores apenas no índice. Tenha cuidado com a abordagem de coluna computada, porque ela pode não se comportar como esperado em alguns casos (problemas com colunas computadas em geral, não específicos para esta situação).Essa abordagem permite que você faça correspondência exata e
LIKE 'xyz%'
diretamente, desde que o termo de pesquisa seja menor que o comprimento indexado.O resultado da
CHECKSUM
função pode ser pequeno, mas não é uma função hash muito boa. Em vez disso, useHASHBYTES
ou uma função CLR.A mesma coisa se aplica acima em relação às colunas computadas. Ou esse valor é pequeno o suficiente (16 bytes) para que possa ser materializado na tabela usando um gatilho ou código de aplicativo e indexado a partir daí.
As desvantagens são que esse método permite apenas correspondência exata, porque não há como corresponder em uma entrada parcial e, é claro, o gerenciamento de alterações necessário para adicionar uma nova coluna não NULL a uma tabela existente.
Você precisará alterar como as consultas acessam a tabela para fazer uma dessas soluções funcionar; portanto, se isso não for possível, você está sem sorte.
Como estamos falando de compactação com perdas (hashing ou truncamento), as consultas sempre precisam também comparar o valor original com o termo de pesquisa, a menos que o índice seja exclusivo, o que pode abrir você para usuários relatando erros estranhos (os primeiros 800 caracteres são idêntico ou uma colisão de hash improvável). Se o índice não for único e os valores originais não forem comparados, resultados incorretos podem ser retornados (observação: isso pode ser uma falha de segurança).
A comparação adicional provavelmente afetará os planos de consulta, e não vou entrar nisso sem uma consulta de amostra, mas você pode encontrar alguns pequenos exemplos na postagem do blog que vinculei acima. Usando o esquema de tabela e as consultas existentes, você deve ser capaz de adivinhar o que acontecerá com os planos.