Ordenação indireta e utilização de indices

Uma das operações mais custosas para um banco de dados é a famosa ordenação, essa é responsavel pela maioria das demoras de algumas querys, normalmente essas ordenações são feitas em memoria, quando se cabe em memoria claro, se não, a mesma sera feita em memoria e em disco, o que tornara sua execução mais pesada ainda, portanto, é necessario tomar muito cuidado com ordenações, claro que muitas vezes elas são necessarias, mas as vezes, sem querer fazemos uma ordenação sem perceber, abaixo segue os cenarios que uma ordenação é feita, seja ela explicita ou não:

Para nossos testes, crei a tebela conforme abaixo:

--CRIA TABELA
CREATE TABLE Funcionarios(ID INT IDENTITY(1,1), Nome VARCHAR(100))

--CARGA DE DADOS
INSERT INTO Funcionarios(Nome) VALUES
('Fabrizzio'),('Antoniaci'),('Caputo'),('Marco'),('Aurelio'),
('Caputo'),('Shirley'),('Antoniaci'),('Caputo'),('Giovanni'),
('Antoniaci'),('Caputo'),('Camila'),('De Lira'),('Cardoso')

Veja que ao realizar um select normal como o abaixo, no plano de execução, um Full Table Scan nessa tabela, ou seja, sem a utilização de indices, esta levando 100%
Query:

SELECT Nome FROM Funcionarios

Ao colocarmos o Distinct em nossa query conforme abaixo

SELECT DISTINCT Nome FROM Funcionarios

Veja que foi adicionado um step denominado sort em nosso plano de execução, verifique que antes a etapa
que antes era 100%, com a adição da operação de sort, a mesma passa a ser apenas 22%, se jogarmos em
uma simples regra de 3 conforme abaixo.
100% no Full table Scan = 10% de uso do servidor
22% no Full Table Scan = Passa a ser apenas 2,2%, fazendo com que 8,8% do servidor seja utilizado apenas para a realização da ordenação.
Se prolongarmos nossa regra de 3, veremos que, uma vez que 2,2% passa a ser 10% do servidor, pois a operação continua a mesma, temos:
2,2% = 10%
8,8% = 40% de utilização de CPU apenas para a operação de ordenação, somando-se com os 10% do FullTable Scan, apenas com o Distinct na query, passamos de uma query de imaginarios 10% de utilização, para 50%, o que é realmente muito!

Com a utilização de um indice conforme abaixo:

CREATE INDEX IX_01 ON Funcionarios(Nome)

Passamos para o plano de execução abaixo, veja que agora, com um indice no campo chave (Nome), todo custo da query passa a ser de leitura do mesmo, como um indice ja é ordenado naturalmente, não temos custo nessa operação, mas ela existe, conforme abaixo:

Outros planos de execução, juntamente com a query acima, que causam ordenação dos dados seguem abaixo:



Preste atenção que uma das respostas mais comuns das pessoas ao perguntar em qual campo se cria um indice é:
O Campo chave do indice deve ser aquele que esta em seu campo where, e os campos no select, quando voce quer montar um indice que cubra 100% da sua query, são colocados na clausula include.
Isso não esta errado, mas esta incompleto, veja que quando voce utiliza qualquer opção listada acima, que ira gerar uma ordenação por aquele campo, é importante que o mesmo possua um indice sim, claro que neste caso não teremos campos no include.

Anúncios
Post a comment or leave a trackback: Trackback URL.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: