Eu tenho várias colunas que armazenam dados que podem conter alguns caracteres extras para formatação/agrupamento. Pense em espaços em branco e traços em dados como números de telefone e números de placas.
Ao consultar, não podemos ter certeza se e onde esses traços estão presentes, então precisamos removê-los da coluna. Fazer isso durante a consulta não é ótimo para o desempenho, então quero criar uma coluna computada para a coluna removida e colocar um índice nela.
-- trimming the length down to 50 characters
-- which is the length of the original field
ALTER TABLE foo
ADD search_license_plate AS (LEFT(REPLACE(license_plate, '-', ''), 50));
CREATE INDEX ix_foo_search_license_plate ON foo(search_license_plate);
Essas colunas computadas são sempre precisas, portanto, não precisam ser persistidas devido à falta de precisão.
Os dados normalmente serão inseridos apenas uma vez e raramente serão alterados. Nunca em grandes volumes, então não me importo muito com qualquer impacto no desempenho de persistir a coluna.
Além disso, a coluna computada nunca será retornada de uma consulta; ele só será usado em condições na consulta, normalmente
SELECT
foo.id,
foo.license_plate
FROM foo
WHERE foo.search_license_plate LIKE '%bar%';
... embora eu não possa garantir que não haverá nada SELECT *
feito nessas mesas.
Existe alguma necessidade de persistir essas colunas?
Geralmente, não, embora haja vários problemas em potencial que exigirão validação com sua carga de trabalho específica e aplicativos cliente.
Os principais requisitos (incluindo
SET
requisitos de opção para todos os clientes) estão listados na documentação em Índices em Colunas Computadas . Você também pode, por exemplo, ser solicitado a adicionar oPERSISTED
atributo por vários motivos, por exemplo, para adicionar uma restriçãoCHECK
ou .NOT NULL
O motivo pelo qual enfatizei a necessidade de testar acima é que o SQL Server às vezes opta por não usar um índice em uma coluna computada (mesmo que persista!) é "obviamente" a melhor estratégia. Para alguns exemplos e informações básicas, consulte meu artigo Colunas computadas adequadamente persistentes .
O resultado é que cada consulta precisa ser testada para garantir que o SQL Server escolha com segurança o índice em que essa estratégia é importante para o desempenho.
Você pode encorajar a seleção do método de acesso ao índice fazendo-o cobrir as consultas de destino (de modo que o índice contenha todas as colunas necessárias para a consulta), mas mesmo isso não vem com garantia. O uso de uma dica de índice vem com uma garantia, mas tem riscos, incluindo gerar um erro se o índice não estiver disponível.
Há também um limite para o qual um índice de b-tree pode ajudar para pesquisas com curinga à esquerda, conforme fornecido na pergunta:
Na melhor das hipóteses, isso resultará em uma varredura completa do índice na coluna computada. Você também pode estar interessado em Trigram Wildcard String Search no SQL Server como uma alternativa.
Ao indexá-los, você os manteve. A
PERSISTED
palavra-chave significa que ela persistiu no índice clusterizado ou heap subjacente. Você simplesmente persistiu em um índice separado. Como um índice é uma cópia dos dados, ele não se aplica exatamente se você estiver apenas copiando a fórmula. Então o que você fez foi persistir.Mas o que você deve considerar é adicionar a
license_plate
coluna como uma coluna incluída em seu índice não clusterizado, para evitar pesquisas.