Processamento de instruções SQL

O processamento de uma única instrução SQL é o modo mais básico para o SQL Server executar instruções SQL. As etapas usadas para processar uma única instrução SELECT que referencia apenas as tabelas base locais (nenhuma exibição ou tabelas remotas) ilustram o processo básico.

Otimizando instruções SELECT

Uma instrução SELECT não é procedural; ela não determina as etapas exatas que o servidor de banco de dados dever usar para recuperar os dados solicitados. Isso significa que o servidor de banco de dados deve analisar a instrução para determinar o modo mais eficiente para extrair os dados solicitados. Isso é conhecido como otimização da instrução SELECT. O componente que faz isso é chamado de otimizador de consulta. A entrada do otimizador consiste em consulta, esquema de banco de dados (definições de tabela e índice) e estatísticas de banco de dados. A saída do otimizador é um plano de execução de consulta, às vezes chamado de plano de consulta ou apenas plano. O conteúdo de um plano de consulta é descrito posteriormente com mais detalhe neste tópico.

As entradas e as saídas do otimizador de consulta durante a otimização de uma única instrução SELECT são ilustradas no seguinte diagrama:

Otimização de consulta de uma instrução SELECT

Uma instrução SELECT define apenas o seguinte:

  • O formato do conjunto de resultados. Isso é especificado principalmente na lista de seleção. Porém, outras cláusulas como ORDER BY e GROUP BY também afetam a forma final do conjunto de resultados.

  • As tabelas que contêm os dados de origem. Isso é especificado na cláusula FROM.

  • A forma pela qual as tabelas estão logicamente relacionadas à finalidade da instrução SELECT. Isso é definido nas especificações de junção, que podem ser exibidas na cláusula WHERE ou em uma cláusula ON seguida de FROM.

  • As condições que as linhas das tabelas de origem devem satisfazer para serem qualificadas para a instrução SELECT. Essas são especificadas nas cláusulas WHERE e HAVING.

Um plano de execução de consulta é uma definição do seguinte:

  • A seqüência em que as tabelas de origem são acessadas.

    Normalmente, há muitas seqüências pelas quais o servidor de banco de dados pode acessar as tabelas base para criar o conjunto de resultados. Por exemplo, se a instrução SELECT fizesse referência a três tabelas, o servidor de banco de dados poderia acessar TableA primeiro, usar os dados de TableA para extrair as linhas correspondentes de TableB e usar os dados de TableB para extrair dados de TableC. As outras seqüências em que o servidor de banco de dados poderia acessar as tabelas são:

    TableC, TableB, TableA ou

    TableB, TableA, TableC ou

    TableB, TableC, TableA ou

    TableC, TableA, TableB

  • Os métodos usados para extrair dados de cada tabela.

    Geralmente, há métodos diferentes para acessar os dados em cada tabela. Se forem necessárias apenas algumas linhas com valores de chave específicos, o servidor de banco de dados poderá usar um índice. Se forem necessárias todas as linhas da tabela, o servidor de banco de dados poderá ignorar os índices e executar um exame na tabela. Se forem necessárias todas as linhas de uma tabela, mas houver um índice cujas colunas de chave estão em um ORDER BY, executando um exame de índice em vez de um exame de tabela, uma classificação separada do conjunto de resultados poderá ser salva. Se uma tabela for muito pequena, os exames de tabela poderão ser o método mais eficiente para quase todos os acessos à tabela.

O processo de selecionar um plano de execução de muitos planos possíveis é chamado de otimização. O otimizador de consulta é um dos componentes mais importantes de um sistema de banco de dados SQL. Enquanto alguma sobrecarga estiver sendo usada pelo otimizador de consulta para analisar a consulta e selecionar um plano, ela será salva várias vezes quando o otimizador de consulta escolher um plano de execução eficiente. Por exemplo, duas empresas de construção podem oferecer projetos idênticos para uma casa. Se, no início, uma empresa ficar alguns dias planejando como a casa será construída, e a outra empresa começar a construir sem planejamento, a empresa que gasta algumas horas para planejar o projeto provavelmente terminará primeiro.

O otimizador de consulta do SQL Server é um otimizador baseado no custo. Cada plano de execução possível tem um custo associado em termos de quantidade de recursos de computação usados. O otimizador de consulta deve analisar os possíveis planos e escolher o que tenha o menor custo estimado. Algumas instruções SELECT complexas têm milhares de planos de execução possíveis. Nesses casos, o otimizador de consulta não analisa todas as combinações possíveis. Em vez disso, usa algoritmos complexos para encontrar um plano de execução que tenha um custo razoavelmente próximo do custo mínimo possível.

O otimizador de consulta do SQL Server não escolhe apenas o plano de execução com o menor custo de recurso; escolhe o plano que retorna resultados ao usuário com um custo razoável em recursos e que retorna os resultados rapidamente. Por exemplo, o processamento de uma consulta em paralelo normalmente usa mais recursos que o processamento em série, mas completa a consulta de forma mais rápida. O otimizador do SQL Server usará um plano de execução paralela para retornar resultados se a carga do servidor não for afetada adversamente.

O otimizador de consulta depende de estatísticas de distribuição ao estimar os custos de recurso de métodos diferentes para extração de informações de uma tabela ou índice. São mantidas estatísticas de distribuição para colunas e índices. Elas indicam a seletividade dos valores em um índice ou uma coluna específica. Por exemplo, em uma tabela que representa carros, muitos carros têm o mesmo fabricante, mas cada carro tem um VIN (número de identificação de veículo) exclusivo. Um índice no VIN é mais seletivo que um índice no fabricante. Se as estatísticas de índice não forem atuais, o otimizador de consulta poderá não fazer a melhor escolha para o estado atual da tabela. Para obter mais informações sobre como manter as estatísticas de índice atualizadas, consulte Usando estatísticas para melhorar o desempenho de consultas.

O otimizador de consulta é importante porque habilita o servidor de banco de dados a ajustar dinamicamente para alterar condições no banco de dados sem exigir a entrada de um programador ou administrador de banco de dados. Isso habilita os programadores a se concentrarem na descrição do resultado final da consulta. Eles podem confiar que o otimizador de consulta criará um plano de execução eficiente para o estado do banco de dados toda vez que a instrução for executada.

Processando uma instrução SELECT

As etapas básicas usadas pelo SQL Server para processar uma única instrução SELECT incluem o seguinte:

  1. O analisador examina a instrução SELECT e a divide em unidades lógicas, como palavras-chave, expressões, operadores e identificadores.

  2. Uma árvore de consulta, às vezes chamada de árvore de seqüência, é criada descrevendo as etapas lógicas necessárias para transformar os dados de origem no formato solicitado pelo conjunto de resultados.

  3. O otimizador de consulta analisa modos diferentes pelos quais as tabelas de origem podem ser acessadas. Ele seleciona a série de etapas que retorna os resultados mais rapidamente e usa menos recursos. A árvore de consulta é atualizada para registrar essa série exata de etapas. A versão final, otimizada da árvore de consulta é chamada de plano de execução.

  4. O mecanismo relacional é iniciado com a execução do plano de execução. Como as etapas que exigem dados das tabelas base são processadas, o mecanismo relacional solicita que o mecanismo de armazenamento rejeite os dados dos conjuntos de linhas solicitados do mecanismo relacional.

  5. O mecanismo relacional processa os dados retornados do mecanismo de armazenamento no formato definido para o conjunto de resultados e retorna o conjunto de resultados ao cliente.

Processando outras instruções

As etapas básicas descritas para o processamento de uma instrução SELECT se aplicam a outras instruções SQL, como INSERT, UPDATE e DELETE. Ambas as instruções UPDATE e DELETE devem direcionar o conjunto de linhas para ser modificado ou excluído. O processo de identificação dessas linhas é o mesmo processo usado para identificar as linhas de origem que contribuem para o conjunto de resultados de uma instrução SELECT. Ambas as instruções UPDATE e INSERT podem conter instruções SELECT incorporadas que fornecem os valores de dados a serem atualizados ou inseridos.

Até as instruções DDL (Linguagem de Definição de Dados), como CREATE PROCEDURE ou ALTER TABLE, são resolvidas no final para uma série de operações relacionais nas tabelas de catálogo de sistema e, algumas vezes, (como ALTER TABLE ADD COLUMN) nas tabelas de dados.