Master the Basics – Queries

Depois de muito pensar sobre temas para falar aqui no blog, decidi me inspirar no conselho do guru de T-SQL, Itzik Ben-Gan:

“Observing true experts in different fields, you find a common practice that they all share – mastering the basics. (…) If you want to master a profession, you need to build your knowledge upon strong foundations.
Put a lot of effort into perfecting your techniques, master the basics, and you’ll be able to solve any problem.”

Uma idéia simples: criar uma série de posts que irão tratar de temas do nosso dia-a-dia como DBAs, entretanto, explorando aspectos normalmente não explorados. Cada tema seria introduzido, na sua forma mais simples e didática possível, e então vamos aumentando o grau de complexidade sobre a discussão do assunto em questão.

Inicialmente vou falar de queries. Vejamos um exemplo de consulta:

SELECT database_id, name
FROM sys.databases
WHERE database_id > 4;

Nada além do que uma simples consulta onde irá exibir as colunas database_id e name da tabela de sistema sys.databases, visualizando o resultado apenas de bancos de dados cujo database_id seja maior que 4.

Não vou explorar nenhum aspecto sobre performance ou sobre boas práticas na escrita de consultas. O que quero tratar aqui é de como o SQL Server resolve esta consulta.
O que acontece quando submetemos esta consulta para o SQL Server executar? A resolução desta query pelo SQL Server é tão simples quanto abrirmos o Management Studio, digitarmos a query, apertamos F5 e pronto, temos o resultado?! Creio que não… Há muito além disto, vamos ver…

A primeira etapa que é realizada para executar uma consulta é estabelecer uma conexão com nosso banco de dados. Para tal, temos a SQL Server Network Interface (SNI), que é uma camada que fará o “meio de campo” entre o client que solicitou a conexão e a nossa instância do SQL Server. Normalmente o protocolo de comunicação utilizado através da SNI é o TCP/IP, mas existem também outros protocolos como Shared Memory, Named Pipes e VIA, mas não entrarei em detalhes sobre eles agora…

Nossa query será enviada para o servidor como um pacote de dados TDS (Tabular Data Stream – outro assunto para falarmos num outro momento… =D). Em nosso servidor temos novamente a SNI para recepcionar os pacotes enviados para serem executados. Ela recebe o nosso pacote, e vendo que se trata de uma query, submete a query para um componente do Relational Engine do SQL Server, o Command Parser.

O papel do Command Parser é fazer o parse da query, validando se a sintaxe está correta, se os objetos existem, e também realizar pequenas simplificações na query. Ao realizar estas validações, o Command Parser irá gerar um hash da nossa query e irá buscar no Plan Cache se existe um plano de execução para a nossa consulta.

Se existir, o plano de execução é carregado e submetido para execução, caso contrário, o Command Parser irá gerar uma sequence
tree (ou query tree), que é uma estrutura interna que será passada para o próximo componente envolvido no nosso processo, o Optimizer.

Falar do Optimizer é tão empolgante quanto complexo, logo, não entrarei em muitos detalhes sobre este componente neste momento… Para ser breve, o Optimizer é baseado em custo, ou seja, para otimizar uma consulta ele se baseia no custo daquela otimização e quem tiver o menor custo, seria escolhido. Um ponto muito importante para se dizer do Optimizer é que ele procura montar um plano de execução “bom o suficiente” para a consulta. Percebeu a sutileza da expressão “bom o suficiente”? Ele não tenta fazer o melhor plano possível, o “the best”. Isso seria muito demorado, muito caro pra se fazer… É bom sempre termos isso em mente.

Vamos considerar então que o Optimizer criou um bom plano para nossa query. Agora, este plano de execução criado é enviado para o Query Executor, que vai conversar com outro grande componente do SQL Server, o Storage Engine. Uma vez que o Query Executor submete nossa query para o Storage Engine, ela é tratada pelos Access Methods, que são, basicamente, estruturas que dirão ao SQL Server como buscar a informação (dados) necessária para atender a nossa consulta. Será papel do Access Methods verificar se os dados necessários estão no Buffer Cache. Se estiverem, os dados serão retornados para o Access Methods que fará o caminho de volta com os dados para o client que fez a consulta.

Considerando que os dados não estão em cache o SQL Server precisa ler estes dados do disco. Vamos lembrar o seguinte, o SQL Server trabalha somente com dados em memória, ou seja, ele irá ler os dados necessários do disco, irá carregá-los no Buffer Cache e posteriormente vai retorná-los para o Access Methods.

Uma vez que nossos dados foram carregados do disco para o Buffer Cache e estes foram entregues para o Access Methods, os dados são enviados de volta para o Relational Engine que se encarrega de retornar estes dados para o client solicitante.

Vejamos abaixo como ficou o fluxo completo de execução da nossa query.

O que podemos concluir com tudo o que vimos. Para um simples mortal que utiliza um sistema e clica num botão “Enviar” para gerar um relatório, o SQL Server nada mais é do que uma caixa preta, onde de alguma forma ele busca os dados que ele pediu. Para nós, especialistas em SQL Server, ele é uma complexa ferramenta que vai muito além de dados e consultas.

As referências utilizadas para este artigo foram as seguintes:

Artigo da Kalen Delaney – Inside SQL Server: Parse, Compile, and Optimize
http://www.sqlmag.com/article/tsql3/inside-sql-server-parse-compile-and-optimize

Livro Inside Microsoft SQL Server 2008 – T-SQL Querying, Capítulo 1 – Logical Querying Processing
http://www.amazon.com/Inside-Microsoft%C2%AE-SQL-Server%C2%AE-2008/dp/0735626030/ref=sr_1_2?ie=UTF8&qid=1311032858&sr=8-2

Livro Professional SQL Server 2008 Internals and Troubleshooting, Capítulo 1 – SQL Server Architecture
http://www.amazon.com/Professional-Server-2008-Internals-Troubleshooting/dp/0470484284/ref=sr_1_1?s=books&ie=UTF8&qid=1311032906&sr=1-1

Espero que seja útil. Sugestões e comentários são muito bem vindos.

Até mais!

Deixe uma resposta

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