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.
Saiba mais sobre o Plano de Execução
Passo 1: Entendendo o Operador Sort
O operador Sort é identificado no Plano de Execução da consulta pelo ícone em destaque na Figura 1.
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.
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.
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.
SELECT Marca
, SUM (Preco)
FROM Venda A
INNER JOIN Carro B ON A.Id_Carro = B.IdCarro
GROUP BY
Marca
ORDER BY Marca
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.
Saiba mais sobre o SQL Server
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)
Saiba mais sobre as melhores práticas com índices
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.
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.
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.
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.
Saiba mais sobre o Processamento no SQL Server