Performance no SQL Server: eliminando o operador Sort

Veja neste artigo como otimizar a performance de consultas no SQL Server através da remoção do operador Sort.

Se você possui uma determinada consulta na sua aplicação que por algum motivo está demorando demais para ser processada, é possível que haja um operador chamado Sort no Plano de Execução. Neste artigo veremos como eliminá-lo e obter ganhos reais em performance no SQL Server.

Passo 1: Entendendo o Operador Sort

O operador Sort é identificado no Plano de Execução da consulta pelo ícone em destaque na Figura 1.

Figura 1. Operador Sort.

Este operador classifica todas as linhas da consulta em ordem. Isto pode levar a um alto consumo de CPU e I/O, dependendo do volume de dados, configuração do servidor, seletividade presente na consulta, etc. Assim, a menos que seja realmente necessário, devemos nos certificar que ele não esteja presente no Plano de Execução.

Passo 2: Criando o ambiente de demonstração

Para demonstrar o impacto do operador Sort e da sua remoção, criaremos duas tabelas, de nomes Carro e Venda, de acordo com a Listagem 1.

Listagem 1. Script de criação das tabelas de exemplo
CREATE TABLE Carro ( IdCarro INT IDENTITY PRIMARY KEY, Modelo VARCHAR(50), Marca VARCHAR(50), Ano VARCHAR(4) ) GO CREATE TABLE Venda ( IdVenda INT IDENTITY PRIMARY KEY, IdCarro INT, Preco NUMERIC(12,2) ) GO ALTER TABLE Venda ADD FOREIGN KEY IdCarro REFERENCES Carro (IdCarro)

Em seguida, basta adicionarmos alguns dados para os testes, conforme o script apresentado na Listagem 2, que populará as duas tabelas.

Listagem 2. Populando as tabelas criadas
INSERT INTO Carro (Modelo, Marca, Ano) VALUES (‘HB20’,’HYUNDAY’,’2015’) , (‘HB20’,’HYUNDAY’,’2012’) , (‘GOL’,’VOLKSWAGEN’,’2001’) , (‘CITY’,’HONDA’,’2014’) , (‘CIVIC’,’HONDA’,’2015’) GO INSERT INTO Venda (Id_Carro, Preco) VALUES (1,23300.00) , (2,26500.00) , (3,12000.00) , (4,28000.00) , (5,45000.00) GO

Passo 3: Realizando a consulta com o Sort

Na Listagem 3 temos um exemplo de consulta que retorna o total de vendas por marca. Ao selecioná-la e pressionar CTRL+L, perceberemos a presença do operador Sort no Plano de Execução, conforme mostra a Figura 2.

Listagem 3. Exemplo de consulta que usa o operador Sort
SELECT Marca , SUM (Preco) FROM Venda A INNER JOIN Carro B ON A.Id_Carro = B.IdCarro GROUP BY Marca ORDER BY Marca
Figura 2. Plano de execução da consulta

Passando o mouse por cima do operador Sort, vemos um resultado semelhante ao da Figura 3, que apresenta um pequeno resumo de estimativa de esforço que o SQL Server teve para ordenar a consulta. Na parte grifada em vermelho, vemos que o SQL Server está ordenando exatamente como solicitamos na Listagem 3.

Figura 3. Detalhes do operador Sort

Passo 4: Eliminando o Sort do Plano de Execução

Para reduzir esse esforço, criaremos um índice na coluna Marca. Os índices são ordenados pelas colunas de modo que o Query Optimizer, que é o responsável pelo nosso Plano de Execução, os identifica e utiliza para evitar o Sort.

O código para sua criação é o seguinte:

CREATE INDEX IDX_Marca on Carro (Marca)

Agora, execute a mesma consulta da Listagem 3, utilizando CTRL + L para exibir o novo Plano de Execução. O retorno será o da Figura 4.

Figura 4. Operador Sort eliminado no Plano de Execução

Perceba que o operador Sort foi eliminado e o Query Optimizer passou a utilizar o índice criado, IDX_Marca. Passe o mouse acima deste novo operador e o resultado será o da Figura 5.

Figura 5. Detalhes da utilização do índice

Conclusão: Comparando ganhos de performance

A Figura 6 exibe um comparativo de ganho de performance, destacando os valores de I/O e Custo do Operador.

Figura 6. Comparativo de performance com e sem o Sort

Perceba que o custo da operação foi reduzido em relação ao Sort, mesmo este sendo apenas um exemplo simples. Em ambientes reais o ganho provavelmente será bem mais expressivo.

Artigos relacionados