Compatibility Level no SQL Server: Quando e Como Utilizar

Ao realizar a migração de um banco de dados para uma nova versão do SQL Server, um detalhe frequentemente ignorado pode afetar diretamente o desempenho das suas consultas: o Compatibility Level (Nível de Compatibilidade).

Neste artigo, você vai aprender:

  • O que é o Compatibility Level

  • Quando e por que alterá-lo

  • Impactos no desempenho e no T-SQL

  • Novidades do SQL Server 2022, como o PSPO

  • Hands-on prático para entender na prática o impacto de cada decisão


🎯 O que é Compatibility Level?

O Compatibility Level é uma propriedade de banco de dados que define como o SQL Server interpretará comandos T-SQL, influenciando desde a sintaxe aceita até o comportamento do otimizador de consultas.

🔍 Exemplo:

Após restaurar um banco criado originalmente no SQL Server 2012 em uma instância 2022, ele pode manter o nível de compatibilidade 110, o que impede que você aproveite as melhorias do otimizador da versão mais recente.


🗓️ Compatibilidade por Versão

Compatibility LevelVersão SQL Server
80SQL Server 2000
90SQL Server 2005
100SQL Server 2008
110SQL Server 2012
120SQL Server 2014
130SQL Server 2016
140SQL Server 2017
150SQL Server 2019
160SQL Server 2022

⚙️ Como Alterar o Compatibility Level

ALTER DATABASE MeuBanco SET COMPATIBILITY_LEVEL = 160

Sempre execute sp_updatestats após a alteração para atualizar as estatísticas do banco:

EXEC sp_updatestats

⚠️ Quando é Risco Mudar?

Alterar o Compatibility Level pode:

  • Melhorar o desempenho com um otimizador mais inteligente

  • Gerar regressões caso queries dependam de comportamentos antigos

  • Quebrar funcionalidades por mudanças na sintaxe ou tipos de dados

📌 Recomendação: habilite o Query Store antes de alterar, monitore por um período, e só então atualize o nível com segurança. Se necessário, utilize o recurso Force Plan para restaurar planos de execução anteriores.


🧪 Casos Práticos: Parameter Sniffing

O famoso Parameter Sniffing acontece quando o SQL Server gera um plano de execução baseado no primeiro valor de parâmetro usado na stored procedure, e o reaproveita — mesmo que ele seja ruim para outros valores.

Cenário:

Prepare o ambiente com o Script abaixo.

/**************************
 Cria tabela
***************************/
IF object_id('dbo.Customer') is not null
   DROP TABLE dbo.Customer

SELECT c.CustomerID as CustomerID,Title,FirstName,MiddleName,Lastname,CompanyName,SalesPerson,
EmailAddress,'Rio de Janeiro' as City, dateadd(d,-CustomerID,getdate()) DataCadastro 
INTO dbo.Customer
FROM AdventureWorksLT.SalesLT.Customer c 

SET IDENTITY_INSERT dbo.Customer ON
DECLARE @i int = 1000 

WHILE @i < 280000 BEGIN
    INSERT dbo.Customer (CustomerID,Title,FirstName,MiddleName,Lastname,CompanyName,SalesPerson,EmailAddress,City,DataCadastro)
    SELECT c.CustomerID + @i as CustomerID,Title,FirstName,MiddleName,Lastname,CompanyName,SalesPerson,
    EmailAddress,'Rio de Janeiro' as City, dateadd(d,-CustomerID,getdate()) DataCadastro 
    FROM AdventureWorksLT.SalesLT.Customer c 
    WHERE FirstName not like 'O%' and CustomerID < 1000

    SET @i = @i + 1000
END
SET IDENTITY_INSERT dbo.Customer OFF
go
/***************** Fim cria tabela ***************************/

-- Altera valor da coluna "City" para uma linha
UPDATE dbo.Customer SET City = 'São Paulo' WHERE CustomerID = 1

-- Cria índice na coluna "City"
CREATE INDEX ix_Customer_City ON dbo.Customer (City)

Parameter Sniffing na prática:

/*************************************************
 Parameter Sniffing (cheirar): Stored Procedure
**************************************************/
go
CREATE or ALTER PROCEDURE spu_CustomerCity
@City varchar(14)
--WITH RECOMPILE
as  
SELECT * FROM dbo.Customer WHERE City = @City
go

SELECT [name] as Banco, compatibility_level FROM sys.databases WHERE [name] = 'HandsOn'

ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 150 -- SQL Server 2019
ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 160 -- SQL Server 2022

/***********************************************************
 - Parameter Sniffing: Stored Procedure
************************************************************/
EXEC spu_CustomerCity 'Rio de Janeiro' --with RECOMPILE
-- Plano ideal "Table Scan": Table 'Customer'. Scan count 1, logical reads 3442

EXEC spu_CustomerCity 'São Paulo' -- with RECOMPILE
-- Plano ideal "Index Seek + Bookmark Loopup": Table 'Customer'. Scan count 1, logical reads 4

🚀 Novidade: Parameter Sensitive Plan Optimization (PSPO)

A partir do SQL Server 2022, o otimizador reconhece quando uma query é sensível ao valor do parâmetro e gera múltiplos planos otimizados, um para cada faixa de valor.

Solução automática e poderosa para mitigar o problema de Parameter Sniffing!


✅ Boas Práticas

  • Após migrações, avalie o Compatibility Level de todos os bancos

  • Habilite o Query Store para controle de planos

  • Teste alterações em ambientes de homologação

  • Use WITH RECOMPILE ou PSPO quando necessário

  • Sempre monitore estatísticas e planos após upgrades

Fui, mas volto com mais SQL Server em breve!

✍️ Sobre o autor
O Prof. Landry é especialista em Microsoft SQL Server desde 1999, Microsoft Trainer, Professor Universitário e criador do canal SQL Server Expert no YouTube, com conteúdo técnico semanal para DBAs e profissionais de dados.

🚀 Quer aprender mais sobre SQL Server?
👉 Me acompanhe no LinkedIn e inscreva-se no canal para não perder nenhuma dica prática!

0
Subscribe to my newsletter

Read articles from SQL Server Expert directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SQL Server Expert
SQL Server Expert

O Prof. Landry Duailibe é especialista em Microsoft SQL Server desde 1999, Microsoft Certified Trainer, professor universitário e criador do canal SQL Server Expert no YouTube, onde compartilha conteúdo técnico semanal para DBAs e profissionais de dados. Já ajudou milhares de alunos a evoluírem suas habilidades com SQL Server e conquistarem melhores oportunidades na área de dados.