Otimizando Performance Com Colunas Computadas


 

Pessoal,
Um outro caso bem legal foi este. Dentre as consultas com problema (pra variar), existiam varias  com where assim :
Where Campo1+campo2 > Valor ou Where campo1 + campo2 * campo3 between valor1 and valor2
Enfim, calculos no where.

A maneira que foi resolvida, usando colunas computadas persisted.

Persisted é uma feature nova que “persisted” a coluna computada, fazendo que ela seja armazenada na tabela e atualizada conforme necessário, prevenindo o overhead do cálculo que existia em versões anteriores. Ela também ajuda na criação de índices, sendo que pra isso ela tem que ser determinística e precisa.

O que isso quer dizer ? Se tivermos uma coluna que por exemplo depende de uma função para fazer cálculos ela não será “persist able”.

Mas vamos lá. Usando o exemplo do post anterior, vamos fazer um select :

select    nome
from    TesteComputed
where    (Valor1 + valor2) > 2000
SELECT [nome] FROM [TesteComputed] WHERE ([Valor1]+[valor2])>@1
  |–Filter(WHERE:([Expr1004]>(2000.00)))
       |–Compute Scalar(DEFINE:([Expr1004]=[DBA].[dbo].[TesteComputed].[ValorTotal]))
            |–Compute Scalar(DEFINE:([DBA].[dbo].[TesteComputed].[ValorTotal]=[DBA].[dbo].[TesteComputed].[Valor1]+[DBA].[dbo].[TesteComputed].[Valor2]))
                 |–Clustered Index Scan(OBJECT:([DBA].[dbo].[TesteComputed].[PK__TesteCom__40F9A2071367E606]))

 

Podemos ver um clustered index scan, que nada mais é um table scan numa tabela com índice cluster.

Agora vamos criar uma nova coluna computada e um índice por ela :

Alter table TesteComputed add ValorTotal as (Valor1 + valor2) Persisted                
Create index idx_TesteComputed on   TesteComputed(valorTotal)            
include (nome)

 

Feito isso vamos rodar a consulta novamente :

select    nome
from    TesteComputed
where    (Valor1 + valor2) > 2000

SELECT [nome] FROM [TesteComputed] WHERE ([Valor1]+[valor2])>@1
  |–Index Seek(OBJECT:([DBA].[dbo].[TesteComputed].[idx_TesteComputed]), SEEK:([DBA].[dbo].[TesteComputed].[ValorTotal] > CONVERT_IMPLICIT(decimal(11,2),[@1],0)) ORDERED FORWARD)

 

Como podemos ver, o plano melhorou muito, isso sem falar no tempo de resposta.

Ta aí, mais uma dica. Mas lembrem-se sempre, tudo tem que ser usado com moderação.

Abraços !!!!

About Laerte Junior

Laerte Junior Laerte Junior is a SQL Server specialist and an active member of WW SQL Server and the Windows PowerShell community. He also is a huge Star Wars fan (yes, he has the Darth Vader´s Helmet with the voice changer). He has a passion for DC comics and living the simple life. "May The Force be with all of us"
This entry was posted in SQL SERVER EM GERAL. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s