[T-SQL Challenge #01] Solução: Filtro em coluna datetime

Fala pessoal tudo bem?
Na semana passada eu postei o [T-SQL Challenge #01] que foi o primeiro post da série de desafios aqui do nosso blog. Eu estou muito feliz com a repercussão que essa série teve, pois houve bastante devolutiva sobre a resolução do desafio e todos acertaram, inclusive um amigo meu que é DBA Oracle.

Antes da resolução do problema, segue abaixo o nome de todos que colaboraram com a resolução do problema.

Fábio Martinho, Tiago Balabuch, Rodrigo Mateus, Sinval Pereira, Lincoln Borges, Bianca Castro, Logan Merazzi, Hugo Torralbo, Marcio Junior, Vitor Gonçalves, Iago Lourenço, Wolney Marconi e Paulo Roberto Correia.

Galera, muito obrigado pela colaboração e parabéns por terem acertado o desafio.

Resolução

A resolução para esse problema onde não podemos alterar a procedure é relativamente simples. Basta criarmos uma coluna computada com a expressão YEAR(OrderDate) na tabela Sales.SalesOrderHeaderEnlarged marcando-a com a opção PERSISTED e após isso indexarmos a coluna computada. Pronto! Problema resolvido.

ALTER TABLE Sales.SalesOrderHeaderEnlarged ADD YearOrderDate AS YEAR(OrderDate) PERSISTED
GO
CREATE INDEX IDX_YearOrderDate ON Sales.SalesOrderHeaderEnlarged(YearOrderDate) INCLUDE(CustomerID, OrderDate)
GO

O Query Optimizer do SQL Server identifica que há uma coluna computada e indexada com a expressão utilizada na procedure sp_getSalesOrder e utiliza a coluna computada e índice para criar o plano de execução e com isso fazer um Index Seek no índice criado.

Galera, isso é SENSACIONAL! Aplausos para o Query Optimizer.

Caso queiram saber mais sobre colunas computadas segue o link oficial da documentação.
https://docs.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-ver15

Vamos ao teste de execução da procedure.

Execution Plan – Procedure sargable
SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

(7853 rows affected)
Table 'SalesOrderHeaderEnlarged'. Scan count 1, logical reads 29, 
physical reads 0, read-ahead reads 0, lob logical reads 0, 
lob physical reads 0, lob read-ahead reads 0.

SQL Server Execution Times:
  CPU time = 16 ms,  elapsed time = 169 ms.

Como podemos notar, tivemos um ótimo ganho de performance. Na execução do desafio tivemos 3522 páginas lidas contra apenas 29 e 419 ms contra 169 ms.

Analisando de forma geral com o intuito de resolver o problema do Index Scan do desafio, podemos dizer que esso é um problema resolvido e que venha o próximo desafio.

Agora, imagine que esse seja um problema do seu mundo real. Ambiente de produção sendo altamente impactado por uma procedure executando uma função para tratar o ano, ou qualquer outro tipo de expressão que a torne uma procedure non-sarg.

Como forma PALIATIVA eu daria essa solução para o time de desenvolvimento com intuito de estabilizar o ambiente, porém eu iria salientar com todos os responsáveis pelo sistema que essa é uma medida PALIATIVA e que a forma DEFINITIVA de solucionar o problema é alterar o código da procedure aplicando as boas práticas para torná-la uma procedure com uma expressão sargable, pois uma coluna calculada persistida e indexada pode impactar em um maior tempo de escrita.

Caso vocês tenham alguma outra solução para esse tipo de problema, por favor, compartilhe conosco. Eu só conheço essa solução.

Pessoal, espero que tenham gostado do primeiro desafio. Mais uma vez nosso muito obrigado a todos que desprenderam seu tempo resolvendo a questão. É isso que nos motiva a escrever e compartilhar um pouco do nosso dia a dia.

Fiquem ligados no nosso blog e canal do youtube.

Até o próximo!

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.