Sie sind auf Seite 1von 13

Introduo ao Query Processor

Autor - Fabiano Neves Amorim

Incio
Escolher o melhor caminho para chegar a determinado lugar pode ser considerado para muitos uma arte, isso porque sempre existem vrios caminhos que levam ao mesmo destino. Executar uma tarefa da forma mais eficiente possvel requer que o caminho percorrido seja o melhor dentre as centenas de variveis que podem influenciar na escolha do melhor percurso. No SQL Server o responsvel por calcular a maneira mais eficiente de acesso aos dados chamado de Query Processor, ele dividido em duas partes, o Query Optimizer e o Query Execution Engine. Veremos neste artigo como o Query Optimizer funciona e quais os passos necessrios para execuo de um comando T-SQL. Entender como funciona e como interpretar o trabalho do Query Optimizer uma das melhores maneiras de aprimorar seus conhecimentos em SQL Server. Esse conhecimento ser de grande valor quando voc precisar fazer algum trabalho de tunning em banco de dados.

Ambiente
Para melhor entendimento dos exemplos deste artigo criaremos uma tabela, com alguns dados e uma viso, que serviro como base para os testes que sero apresentados. A Listagem 1 contm o script para criao destes objetos. O Script cria a tabela Funcionarios com algumas informaes (ID, Nome, Salrio, Telefone e Cidade) e, em seguida, so inseridos alguns registros. Logo aps, uma view (vw_Funcionarios) criada. A grosso modo, podemos dizer que Views so tabelas virtuais definidas por uma consulta T-SQL. A nossa view, criada na Listagem 1, retorna o nome e o salrio de todos os funcionrios que ganham mais de R$ 900,00. CREATE TABLE Funcionarios(ID Nome Salario Telefone Cidade Int IDENTITY(1,1) PRIMARY KEY, VarChar(30), Numeric(18,2), VarChar(15), VarChar(80));

INSERT INTO Funcionarios(Nome, Salario, Telefone, Cidade) VALUES('Jos', 850.30, '11-55960015', 'So Paulo'); INSERT INTO Funcionarios(Nome, Salario, Telefone, Cidade) VALUES('Antonio', 950, '11-81115544', 'So Paulo'); INSERT INTO Funcionarios(Nome, Salario, Telefone, Cidade) VALUES('Joo', 1200, '11-44123321', 'So Paulo'); CREATE VIEW vw_Funcionarios AS SELECT Nome, Salario FROM Funcionarios WHERE Salario > 900
Listagem 1. Script para criao dos objetos de teste

Query Optimizer
Quando um comando T-SQL executado no SQL Server o Query Processor entra em ao para gerar um plano de execuo. Este plano dir qual a melhor maneira de acessar os dados gastando menos recursos e com o desempenho mais eficiente possvel. Podemos observar na Figura 1 a ao do Query Optimizer (em vermelho) e uma srie de passos para compilar e executar um comando T-SQL. Vamos analisar melhor este comportamento.

Figura 1. Fluxograma de passos necessrios para gerar um plano de execuo

Supondo que um SELECT simples, por exemplo, SELECT * FROM Funcionarios, seja enviado ao servidor, a primeira tarefa que o Query Processor far com o comando verificar se o mesmo est no Cache Plan (mais informaes sobre o Cache Plan no final do artigo). Caso ele no esteja em cache, o Query Processor enviar o comando para os processos de Parse e Bind. O Parse/Bind executa um processo conhecido como Algebrizer. Durante este processo o SQL tenta encontrar possveis erros de escrita na sintaxe e lgica do comando. Por exemplo, o comando select id from tab1 group by nome gera uma exceo, pois a coluna i d no pertence ao group by e no est utilizando uma funo de agregao (SUM, COUNT, ...). O Algebrizer tambm expande as definies do comando, isso significa que ele troca select * por select col1, col2, col3..., ou select col1 from View pelo nome das tabelas envolvidas na view. Sempre que uma view referenciada em uma consulta, o SQL Server acessa as tabelas que contm os dados. Na Figura 2, por exemplo, podemos visualizar que o SQL acessa a tabela Funcionarios para ler os valores das colunas Nome e Salario.

Figura 2. Ilustrao de uma View acessando uma tabela.

Outro passo ser resolver os nomes e tipos de objetos envolvidos na consulta. Pode acontecer de haver um sinnimo para uma determinada tabela que est em outro servidor. Quando isso acontece, o SQL precisa identificar que este sinnimo faz referncia a um objeto que est em outro banco de dados, e este banco pode estar at mesmo ligado a outro servidor utilizando um Linked Server. Aps estas anlises o Parse/Bind retorna um binrio chamado Query Processor Tree, que uma representao lgica dos passos necessrios para a execuo do comando SQL. O Query Processor Tree enviado para o prximo passo da execuo da consulta, que a anlise do Query Optimizer. importante destacar que nem sempre um comando enviado para a anlise do Query Optimizer. Por exemplo, alguns comandos DDL, tais como o CREATE Table, que so de definio das estruturas dos dados, no tm necessidade de uma anlise do Query Optimizer, pois s h uma forma de o SQL executar esta operao. Quando o Query Optimizer recebe o Query Processor Tree, ele dar inicio a uma srie de anlises a fim de encontrar qual a maneira mais eficiente de acessar os dados desejados. O Query Optimizer trabalha baseado no custo de cada operador de acesso a dados, ou seja, ele tenta encontrar a maneira que gastar menos recursos para retornar os dados. Tambm levada em considerao a velocidade de execuo da consulta, por exemplo, ele pode decidir por utilizar paralelismo a fim de retornar os dados mais rapidamente. Ao optar por este recurso, o SQL utiliza mais de um processador para executar uma consulta. Dessa forma, o gasto com recursos se torna maior, j que mais processadores sero utilizados, porm, o tempo de retorno tende a ser menor comparado a execuo em apenas um processador. Durante a fase de anlise o Query Optimizer realiza algumas tarefas, entre elas: identificar todos os possveis argumentos de pesquisa que podem estar especificados na clusula WHERE e verificar se existem Joins entre tabelas que devem ser otimizados. Baseado nestas informaes, ele analisa quais as opes de acesso aos dados, quais ndices deve utilizar, em qual ordem os Joins devem ser realizados e qual o melhor algoritmo de Join para cada operao. Na anlise do Query Optimizer tambm existe um processo chamado Simplification, que executado logo no inicio da otimizao. Uma das tarefas do Simplification conhecida como Predicate PushDown, onde ele tenta reescrever sua consulta jo gando os argumentos de pesquisa para a clusula where (veja a Listagem 2). SELECT * FROM Funcionarios INNER JOIN Funcionarios AS Funcionarios2 ON Funcionarios.ID = Funcionarios2.ID

AND Funcionarios.Nome = 'Antonio' WHERE Funcionarios.ID > 1


Listagem 2. Consulta com argumentos de pesquisa especificados no join

Com base na consulta da Listagem 2, quando o comando for executado, durante a fase de Simplification, o SQL ir reescrever a segunda consulta deslocando o argumento de pesquisa (Funcionarios.Nome = Antonio) para a clusula where, como pode ser visto na Listagem 3. SELECT INNER ON WHERE AND * FROM Funcionarios JOIN Funcionarios AS Funcionarios2 Funcionarios.ID = Funcionarios2.ID Funcionarios.ID > 1 Funcionarios.Nome = 'Antonio'

Listagem 3. Consulta com argumentos de pesquisa especificados no where

Na Figura 3 temos uma simples representao grfica de como o Query Optimizer funciona. Como pode ser visto, o resultado da anlise ser o Query Plan, ou plano de execuo.

Figura 3. Query Optimizer

Na Figura 4 podemos visualizar a representao grfica de um plano de execuo simples. Com base na estrutura da tabela Funcionarios, podemos verificar na Figura 4 que para o comando SELECT * FROM Funcionarios, o Query Optimizer gerou um plano de execuo que acessa a tabela Funcionarios utilizando o operador Clustered Index Scan. Durante a criao de uma tabela o SQL Server automaticamente cria um ndice clustered para as colunas definidas como primary key. Este o comportamento default, e pode ser alterado definindo a primary key como nonclustered no comando de criao da tabela. O SQL utilizou este ndice clustered para ler os dados da tabela Funcionarios. Veremos mais informaes sobre operadores na seo Operadores.

Figura 4. Execution Plan gerado pelo Query Optimizer

Visualizando o Plano de execuo


Existem trs maneiras de visualizar um plano de execuo: o modo grfico, modo texto e XML. Vamos analisar os dois modos mais utilizados para anlise: grfico e texto. Para visualizar o plano de execuo em modo grfico, basta digitar um cdigo T-SQL no SQL Server Management Studio e pressionar ctrl+l. Neste modo diversas informaes complementares so exibidas. Estas informaes so chamadas de hints. Os hints contm informaes importantes sobre o objeto que est sendo acessado ou sobre a operao que ser executada, por exemplo, dados sobre a utilizao de memria, CPU e custo de execuo de cada operador dentro de todo o plano de execuo. Tambm so apresentados dados informando se o resultado do operador est ordenado ou no, nmero estimado de linhas que sero retornadas e etc. Para exibir os hints de um determinado operador, basta posicionar o cursor do mouse sobre o operador desejado. Na Figura 5, por exemplo, podemos analisar diversas informaes em relao aos custos gerados pelo operador Clustered Index Scan. Entre elas: Actual Number of Rows: Nmero de linhas retornadas pelo operador; Estimated I/O Cost: Valor relativo ao custo de I/O necessrio para executar o operador. desejado que este valor seja o menor possvel; Estimated CPU Cost: Valor relativo ao custo de CPU necessrio para executar o operador. desejado que este valor seja o menor possvel; Estimated Operator Cost: Este o custo do operador dentro de todo o plano de execuo. Um percentual de custo exibido entre parnteses. Uma lista completa com a descrio de cada valor exibido pode ser encontrada no Help do SQL Server.

Figura 5. Hint com dados do plano de execuo

Como podemos perceber, o valor exibido nas informaes de Cost um nmero sem um real sentido, pois no o custo em milissegundos, nem o nmero de IO. Este valor utilizado internamente pelo Query Optimizer para identificar qual ser o melhor operador a ser utilizado.

O modo grfico de visualizao a maneira mais simples de analisar planos de execuo. Seguem alguns pontos que so importantes de serem destacados: Possui uma interface que facilita a visualizao dos hints e a compreenso do plano de execuo; Fcil de encontrar possveis pontos de conteno, isto , operadores que possuem alto valor de custo. Cada operador possui um valor de 0 a 100%, onde apresentada a porcentagem de custo de execuo de cada um em relao a todo o plano de execuo. Ao analisar o plano, podemos facilmente identificar quais so estes operadores; Pode ser salvo em formato XML e aberto no SQL Server Management Studio (somente SQL Server 2005 e posterior). Outra maneira de visualizar os planos de execuo utilizando o modo texto. Para habilitar a exibio do plano de execuo neste modo necessrio ativar uma das opes de ShowPlan, so elas: SET SHOWPLAN_TEXT ON: Retorna o plano de execuo de cada comando do batch. Os comandos no so executados, portanto o plano de execuo o estimado, e no o atual; SET SHOWPLAN_ALL ON: Semelhante ao SHOWPLAN_TEXT, a diferena entre eles que o SHOWPLAN_ALL retorna mais informaes sobre o plano; SET STATISTICS PROFILE ON: Retorna o plano de execuo completo, semelhante ao SHOWPLAN_ALL, com a diferena de que o PROFILE executa os comandos do batch, gerando o plano atual; SET SHOWPLAN_XML ON: Retorna o plano de execuo em um XML formatado. No executa os comandos do batch. SET STATISTICS XML ON: Semelhante ao SHOWPLAN XML, com a diferena de que o STATISTICS XML executa o batch. Como exemplo, execute o comando SET SHOWPLAN_TEXT ON e depois execute a consulta SELECT * FROM Funcionarios. O resultado ser a exibio do plano de execuo em modo texto, como pode ser visto Listagem 4. SELECT * FROM Funcionarios |--Clustered Index Scan(OBJECT:( [dbo].[Funcionarios].[ PK_Funciona__3214EC277D430130])) Listagem 4. Exemplo de consulta e plano de execuo em modo texto Este plano exatamente o mesmo que visualizamos na representao grfica da Figura 4. Ele representa uma simples leitura dos dados da tabela Funcionarios, utilizando operador Clustered Index Scan, que acessa o ndice PK__Funciona__3214EC277D430130. Na Listagem 5 podemos visualizar um plano de execuo em modo texto para um update na tabela Funcionarios. Observe que o texto apresentado contm muitas funes de processos internos do SQL Server, o que acaba fazendo com que o plano fique complexo de entender. Entretanto, muitas vezes ele a melhor maneira de se analisar o que o SQL est fazendo. Sobre este modo, os pontos que merecem destaque so: Mais fcil para analisar grandes planos de execuo, pois o plano fica bem organizado em uma rvore hierrquica. A rea de visualizao dos planos em modo grfico exige que tenhamos que ficar arrastando as barras de rolagem de um lado para o outro, tornando a anlise um pouco mais difcil; Todas as informaes j so exibidas, no precisa dos hints; Fcil para exportar para Excel ou enviar por e-mail.

UPDATE Funcionarios SET Nome = 50 WHERE ID = '10' UPDATE [Funcionarios] set [Nome] = @1 WHERE [ID]=@2 |--Clustered Index Update(OBJECT:( [dbo].[Funcionarios].[PK]), SET:( [dbo].[Funcionarios].[Nome] = [Expr1003]), DEFINE:([Expr1003]=CONVERT_IMPLICIT(varchar(30),[@1],0)), WHERE:( [dbo].[Funcionarios].[ID]=CONVERT_IMPLICIT(int,[@2],0)))
Listagem 5. Exemplo de consulta e plano de execuo em modo texto

Operadores
Os cones que so exibidos nos planos de execuo (Figura 6) so conhecidos por operadores. Eles so os responsveis por executar as operaes necessrias para rodar um comando T-SQL. Existem diversos operadores e ao longo dos artigos sobre o Query Optimizer veremos mais alguns deles. Dessa forma, vamos entender um pouco mais sobre como eles se comportam, quando e porque so necessrios. Operadores executam e calculam tarefas geradas pelo plano de execuo, por exemplo, um operador de Nested Loop executa um Join. Operadores de Index Seek fazem leitura de um range de valores em um ndice, por exemplo, uma consulta que deseja retornar os dados de uma tabela onde o valor da coluna Cdigo esteja entre 5 e 10, em uma tabela que contm registros de 0 a 100, o SQL pode usar o operador de Index Seek para ler apenas as pginas de dados do ndice que contm as linhas com os valores de 5 a 10. Operaes de agregao como MAX, MIN, SUM, COUNT e AGV so calculadas pelo operador de Stream Aggregate. O Stream Aggregate agrupa todas as linhas de uma tabela por uma ou mais colunas, calculando o valor do comando de agregao utilizado na consulta. Por exemplo, uma consulta que deseja retornar quantos pedidos os clientes fizeram em 2008 agrupado pelo nome do cliente; neste caso, o SQL ir utilizar o Stream Aggregate para agrupar todos os clientes em uma linha e calcular o SUM da quantidade de pedidos. Como j mencionado, para produzir o melhor plano de execuo o Query Optimizer analisa qual o melhor tipo de operador para executar determinada tarefa, tentando encontrar qual deles executar o processo mais rpido e/ou utilizando a menor quantidade de recursos. Todo operador executa os mtodos Open(), GetRow() e Close(). Devido a esta caracterstica, os operadores so independentes, e, por isso, o SQL consegue gerenci-los com maior facilidade. Como no existe dependncia, um operador SORT pode ser utilizado para ordenar um resultado ou pode ser utilizado para ordenar uma coluna, a fim de saber qual o maior valor (MAX) da tabela. Isso faz com que o Query Optimizer tenha mais opes de escolha sobre qual operador utilizar. Uma caracterstica importante a ser destacada que existem duas categorias de operadores: os operadores nonblocking e os operadores blocking ou stop-and-go: Os operadores nonblocking so aqueles que lem as linhas do input e produzem o output ao mesmo tempo. No mtodo conhecido por GetRow(), conforme a leitura das linhas vai acontecendo, o operador executa sua tarefa e retorna o output para o prximo operador fazer seu trabalho. O operador de Nested Loop um bom exemplo desse comportamento. Assim que a primeira linha recebida (GetRow()) o SQL faz o Join com a tabela do outer, e caso o relacionamento seja verdadeiro a linha retornada no output. Este processo se repete at o fim da leitura da tabela do Join;

J os operadores blocking necessitam primeiro ler todas as linhas (normalmente no mtodo Open()) do input para depois retorn-las para o output. Um exemplo clssico de operadores blocking o Sort, que necessita primeiro ler todas as linhas do input para fazer a ordenao e, por fim, retornar as linhas ordenadas. Existem alguns cenrios onde cada tipo de operador melhor aproveitado, por exemplo, operadores nonblocking so preferveis quando utilizamos as clusulas TOP, Hint FAST N ou mesmo um Exists. Como exemplo vamos utilizar o comando Exists. Este comando utilizado para validar se um valor existe dentro de um contexto. Normalmente ele utilizado junto com subqueries para validar se um valor existe em uma tabela. Durante a execuo do Exists, se ao menos uma linha for retornada para o output, isso j caracteriza uma condio verdadeira. Ou seja, se houve algum retorno, isso significa que o valor existe, e neste caso o Query Execution (responsvel por executar os planos gerados pelo Query Optimizer) encerra o processo de leitura (GetRow). Apenas uma linha o suficiente para saber se o valor procurado existe ou no. Se tivermos que esperar todas as linhas serem lidas para depois retornar o output, como os operadores blocking fazem, esta vantagem de encerrar o processo assim que encontrar alguma linha no seria aproveitada. Existem pouco mais de 100 operadores, entre eles: Scan, Compute Scalar, Aggregate, Sort, Spools e Key Lookup, apresentados na Figura 6.

Figura 6. Alguns operadores do plano de execuo

Para finalizar esta seo importante citar que no existe o melhor operador para fazer um Join ou uma Agregao. Cada operador melhor para uma determinada situao.

Cache
Como podemos observar, o processo de gerao de um plano de execuo bem complexo e requer um tempo extra na execuo da consulta. Quanto maior e mais complexa for sua consulta, mais tempo o Query Processor leva para analisar todas as variantes, e por fim gerar um plano de execuo para o comando T-SQL. Toda essa operao de gerar o plano de execuo causa delay e normalmente faz alto uso de CPU. Por isso, o SQL Server usa um mecanismo para evitar que toda vez que uma consulta for enviada para o banco, o Query Processor tenha que gerar um novo plano de execuo. justamente este o papel do Cache Plan: evitar que uma consulta que j tenha passado pelo Query Optimizer seja enviada novamente para otimizao. Conforme podemos observar no fluxograma (Figura 1), o primeiro processo que o Query Processor faz procurar no cache se j existe um plano de execuo para a consulta enviada ao servidor. Isso significa que quando um plano de execuo gerado para uma determinada consulta, o SQL grava este plano em uma rea de memria a fim de reutilizar o mesmo plano de execuo para consultas semelhantes. A rea de memria utilizada para armazenamento dos planos de execuo exatamente a quantidade de memria disponvel para uso do servidor SQL Server. No SQL Server 7.0 havia uma rea especfica para o armazenamento dos planos, chamada procedure cache . Porm, a partir da verso 2000 isso foi alterado para que o SQL pudesse utilizar toda a memria disponvel ao SQL Server. Na verdade, no SQL Server 7.0 s eram armazenados planos de execuo de procedures

(por isso se chamava procedure cache), consultas ad-hoc no tinham o plano armazenado em cache. Reutilizando planos de consulta Em muitas ocasies, reutilizar o plano de execuo pode ser uma grande vantagem, j que economizamos todo o tempo que seria gasto pelo Query Processor para analisar um novo plano. Entretanto, reutilizar um plano de execuo que est armazenado em cache pode ser um problema, pois nem sempre a mesma consulta retorna a mesma quantidade de dados. Por isso, o SQL Server bem cauteloso quando estamos falando de reutilizao de planos de execuo, j que pode haver situaes onde um mesmo plano no seja o ideal para consultas parecidas. Por exemplo, vamos imaginar que uma consulta que retorna apenas 10 linhas seja enviada pela primeira vez para o SQL Server, e o Query Processor gerou um plano de execuo que utiliza um ndice nonclustered mais um bookmark para ler uma pequena quantidade de registros. Nestas condies o Query Engine executa este plano e depois o armazena em cache. Agora imagine que uma nova consulta, igual primeira, seja enviada para o SQL Server, mas desta vez a condio de busca informada no where requeira que milhares de linhas sejam retornadas. Se o SQL optar por reutilizar o plano de execuo isso no vai ser bom, pois bem provvel que seja melhor fazer um Scan em toda a tabela do que utilizar o ndice mais o bookmark. O cenrio descrito bastante comum de acontecer. Outro fator importante de ser observado que algumas operaes podem deixar um plano que est em cache desatualizado. Por exemplo, pode acontecer do schema que envolve a consulta ser alterado, ou um novo ndice ser criado ou at mesmo apagado. Nestas situaes o SQL no conseguir reutilizar o plano de execuo, o que resulta em uma nova anlise do Query Processor. Existem diversas maneiras de saber se um plano de execuo foi reutilizado ou no. Para isso abra uma consulta no SQL Server Management Studio e execute o cdigo da Listagem 6. Na primeira linha executado um comando (DBCC FREEPROCCACHE) para limpar a rea de cache atual, apagando todos os planos de consulta que esto armazenados em memria. Feito isso, so executadas trs simples consultas para retornar os dados de um determinado funcionrio especificado na clusula where. Por fim, selecionamos os registros da sys.dm_exec_cached_plans, que uma view do sistema que retorna os planos de execuo que esto em cache. Esta view retorna uma coluna chamada plan_handle que do tipo binrio. Para converter este valor binrio para um texto, o SQL disponibiliza uma function do sistema chamada sys.dm_exec_sql_text. Ela l uma entrada em binrio e retornar uma coluna chamada text, que contm o plano em modo texto. DBCC FREEPROCCACHE; GO SELECT * FROM Funcionarios WHERE Nome = 'Jos' GO SELECT * FROM Funcionarios WHERE Nome = 'Antonio' GO SELECT * FROM Funcionarios WHERE Nome = 'Jos' GO SELECT usecounts, cacheobjtype, objtype, "text" AS Comando_SQL FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text (plan_handle) WHERE cacheobjtype = 'Compiled Plan' AND "text" NOT LIKE '%dm_exec%';
Listagem 6. Exemplo de consulta e acesso ao cache plan

O resultado do comando acima deve ser parecido com os registros da Tabela 1. UseCounts CacheObjType Compiled Plan 1 Compiled Plan 2 Objtype Comando_SQL

Adhoc SELECT * FROM Funcionarios WHERE Nome = 'Antonio' Adhoc SELECT * FROM Funcionarios WHERE Nome = 'Jos' Tabela 1. Valores que esto em cache retornados pela DMV sys.dm_exec_cached_plans

A DMV (Dynamic Management Views) sys.dm_exec_cached_plans retorna todos os planos de execuo que esto armazenados no cache do SQL Server. Voc pode utilizar esta view para saber se um determinado plano foi reutilizado ou no, a quantidade de memria que um plano est utilizando e tambm para verificar quantas vezes um plano foi reutilizado. A coluna UseCounts retorna a quantidade de vezes em que o plano de execuo foi reutilizado. A coluna CacheObjType retorna o tipo do objeto em cache. Ela pode apresentar os seguintes valores: Compiled Plan: Representa um plano de execuo completo; Compiled Plan Sub: Existe uma propriedade do banco chamada optimize for ad hoc workloads. Quando habilitada, assim que uma consulta AdHoc enviada pela primeira vez ao SQL, ele grava um Plan Sub no cache, no com o plano completo, mas somente com um Plan Sub. Isso vai permitir que o SQL reconhea que um plano j foi gerado para esta consulta. A partir da segunda execuo deste comando, o SQL substitui este plano pelo plano completo; Parse Tree: Representa o parse de uma view, function, etc.; Extended Proc: Grava o plano para extended procedures, por exemplo, a xp_cmdShell; CLR Compiled Func: Funes criadas utilizando CLR; CLR Compiled Proc: Procedures criadas utilizando CLR. A coluna Objtype retorna qual o tipo do objeto que est armazenado, por exemplo, pode ser um comando Adhoc, proc, view, trigger, entre outros. Observe na Tabela 1 que a coluna UseCounts contm o valor 2 para a consulta SELECT * FROM Funcionarios WHERE Nome = 'Jos', mostrando que o SQL Server utilizou duas vezes o mesmo plano de execuo. Uma observao importante em relao ao cache plan que para consultas adhoc, que no estejam parametrizadas (ou seja, iguais a que utilizamos acima), para que o Query Processor consiga fazer proveito do plano que est em cache as consultas precisam ser escritas exatamente iguais. Inclusive os valores no where tero que ser os mesmos. Repare que no exemplo da Listagem 6 o SQL s reutilizou o plano de execuo em cache porque a terceira consulta enviada para o servidor idntica primeira consulta, inclusive o WHERE Nome = Jos. Isso significa que cada caractere ser analisado e comparado com o comando em cache. Uma simples quebra de linha ou uma letra maiscula ou at mesmo um cdigo de comentrio j ser o suficiente para inviabilizar o uso do plano em cache, acarretando na criao de um novo plano de execuo. Parametrizao Sempre que possvel o SQL Server tenta alterar sua consulta para torn-la apta reutilizao dos planos de execuo. Este comportamento chama-se parametrizao. Consultas parametrizadas tm mais chances de terem seu plano de execuo reutilizado. No SQL Server 2005 existem dois tipos de parametrizao, o Simple Parameterization (conhecido como auto-parameterization, no SQL Server 2000) e Forced Parameterization. Ao

utilizar a parametrizao Simple, o SQL mais cauteloso em relao s quais consultas parametrizar, j a opo forced tenta parametrizar a maior quantidade de consultas possvel. Quando um banco de dados criado o padro de parametrizao o Simple. Para alterar esta opo acesse as propriedades do banco de dados e selecione a opo Forced na propriedade Parameterization. Quando a opo Forced est selecionada o SQL tenta parametrizar a maior quantidade de consultas possveis. Existe uma lista de instrues que impedem o uso de parametrizao. Esta lista pode ser acessada no help do SQL Server. Durante o processo de parametrizao o SQL Server tenta alterar o valor no where por uma varivel, e futuramente ele altera este valor pelo novo valor informado na consulta. O SQL Server bem cauteloso em relao a quando parametrizar uma consulta. Este processo somente ser adotado para consultas que so consideradas seguras. Uma consulta segura quando o plano selecionado no muda caso os parmetros (filtros) mudem. Vejamos um exemplo de consulta considerada segura: Para uma consulta que busca por um valor em uma tabela, passando um filtro para uma coluna que contm um ndice nico, o SQL sabe que apenas um valor ser retornado. Independente do valor do parmetro recebido, pois a presena do ndice nico obriga que exista apenas um registro com o mesmo valor em toda a tabela. Vejamos um exemplo de consulta considerada no segura: Fazer um seek, ou seja, ler um range de informao a partir de um ndice pode ser uma tima escolha. Por outro lado, utilizar este mesmo plano para uma consulta que retorna vrias linhas pode no ser a melhor opo. Vamos analisar um exemplo de parametrizao e reutilizao do plano de execuo. Para isso execute o cdigo da Listagem 7. Neste cdigo, executamos duas simples consultas que retornam os dados dos funcionrios, com base no ID especificado na clusula where. Como a coluna ID a chave primria da tabela funcionrios, os valores de ID no podem se repetir. Isso caracteriza esta consulta como segura para reutilizao do plano de execuo. Podemos observar na Tabela 2 que o SQL reutiliza o mesmo plano para as duas consultas. SELECT WHERE GO SELECT WHERE GO SELECT FROM CROSS WHERE AND * FROM Funcionarios ID = 1 * FROM Funcionarios ID = 2 usecounts, cacheobjtype, objtype, "text" AS Comando_SQL sys.dm_exec_cached_plans APPLY sys.dm_exec_sql_text (plan_handle) cacheobjtype = 'Compiled Plan' "text" NOT LIKE '%dm_exec%';

Listagem 7. Exemplo de consulta parametrizada

O resultado de execuo da Listagem 7 deve ser parecido com os registros da Tabela 2. UseCounts CacheObjType Compiled Plan 1 Compiled Plan 1 Objtype
Adhoc Adhoc

Comando_SQL
SELECT * FROM Funcionarios WHERE ID = 2 SELECT * FROM Funcionarios WHERE ID = 1

(@1 tinyint)SELECT * FROM [Funcionarios] WHERE [ID]=@1 Tabela 2. Valores que esto em cache retornados pela DMV sys.dm_exec_cached_plans

Compiled Plan

Prepared

Como podemos observar nas colunas UseCounts e Objtype, o SQL Server gerou um plano de execuo prepared e ele foi utilizado duas vezes. As outras consultas continuam aparecendo, mas elas no contem o plano de execuo, elas apontam para a linha que tem o plano de execuo prepared. Infelizmente com as DMVs e recursos disponibilizados pelo SQL Server, no possvel visualizar esta ligao entre os planos Adhoc e o plano Prepared, este um cdigo interno do SQL. Estas consultas Adhoc so conhecidas como Shell Queries, elas so armazenadas para agilizar o processo de reutilizao do plano. Veja na Figura 7 um exemplo de como estas consultas podem ajudar na performance da execuo do comando.

Figura 7. Fluxograma de procura por plano de execuo em cache

Nesta figura podemos observar que quando um mesmo comando for executado, caso ele contenha um shell query no cache, o SQL pula uma etapa do processo de localizao do plano. Observe na Tabela 2 que a linha 3 possui o plano de execuo parametrizado, que o plano prepared. O plano prepared foi gerado baseado nas consultas executadas pelo cdigo da Listagem 7. Como podemos observar, o SQL Server trocou o valor no where por uma varivel @1 e declarou a varivel como datatype tinyint. Ao parametrizar uma consulta o SQL tenta encontrar qual a melhor opo de varivel a ser utilizada, neste caso, ele optou pelo tinyint por ela ocupar apenas 1 byte de armazenamento. O datatype tinyint consegue tratar valores de 0 a 255, isto , caso o valor informado no where seja 300 o SQL no conseguir utilizar este plano de execuo, causando uma nova recompilao do comando.

Figura 8. Exemplo de consulta parametrizada

Na Figura 8 podemos visualizar como funciona o conceito de parametrizao. Ao parametrizar o valor de where Prikey, o SQL consegue reutilizar o mesmo plano de execuo para as trs consultas apenas alterando o valor de ?.

Concluso
Vimos neste artigo quais os mtodos que o SQL Server utiliza para executar uma consulta SQL e como o Query Processor trabalha para acessar os dados armazenados nos arquivos de banco de dados. Ao acessar os dados, estudamos um pouco dos operadores de acesso a dados, bem como os tipos de operadores. Tambm vimos como analisar um plano de execuo e as anlises em modo grfico e modo texto. Por ltimo foi apresentado o conceito de Cache Plan e parametrizao de consultas. Linked Server: um mecanismo que permite que o SQL Server execute comandos em outro banco de dados OLE DB. Ao criar um linked Server o SQL cria uma conexo com o banco de dados destino, permitindo que os dados que esto armazenados no banco destino sejam acessados a partir da prpria instancia do SQL Server. Por exemplo, possvel abrir uma consulta no SSMS e fazer um update em uma tabela do SQL Server lendo os dados de uma base Oracle. O banco utilizado no Linked Server pode ser remoto ou local. Podemos criar um linked Server com um banco de dados Access, Oracle, MySQL, ou qualquer banco de dados que contenha um driver OLE DB. OLE DB: (Object Linking and Embedding, Database) um pacote que contm as informaes necessrias para conexo e gerenciamento da leitura dos registros armazenados em uma fonte de dados (arquivos txt, xls, entre outros) ou bancos de dados.

Das könnte Ihnen auch gefallen