Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Este o segundo artigo de uma srie que pretende apresentar recursos da linguagem SQL que ajudam na criao de relatrios. Repetindo o que escrevi no primeiro artigo: consenso entre os especialistas que SQL no a melhor linguagem para criao de consultas complexas. Apesar de esta ser uma verdade inegvel, muito comum nos depararmos com situaes em que ele, o SQL, a nica ferramenta que temos mo para criao de um relatrio. Isso ocorre muitas vezes por questo de custos, j que nem sempre economicamente vivel optar pela compra de uma soluo especializada. Este cenrio muito comum no dia-a-dia das empresas e, no fim das contas, somos forados a us-lo. Por esta razo, eu considero importante que todo profissional de banco de dados conhea os principais recursos do SQL para atender as solicitaes dos seus usurios. Neste sentido, importante relembrarmos uma definio bsica ao se trabalhar com
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 1/14
8/4/2014
consultas SQL que a definio de expresso SQL. A definio que temos para o termo expresso bastante simples: uma expresso retorna um valor. Os tipos utilizados em uma expresso variam bastante, cobrindo diferentes tipos de dados como string, numeric e boolean. Na verdade, quase tudo que inserirmos depois do SELECT ou FROM em um comando SQL pode ser considerado uma expresso. Caso voc queria encontrar um item ou grupo de itens em particular em seu banco de dados, voc precisar fazer uso de uma ou mais condies em suas queries. Podemos definir condies em consultas SQL utilizando a clusula where. Vimos no artigo anterior vrios recursos teis da linguagem SQL que nos ajudam na criao de relatrios. Neste texto atual, apresentaremos recursos da linguagem SQL para gerao de objetos especiais para manipulao dos dados, como vises e consultas aninhadas. O leitor com alguma familiaridade com SQL j deve ter visto tais recursos, por isso acrescentaremos aqui um estudo de performance para auxili-lo a explorar estas tcnicas de forma otimizada. Este material foi extrado de uma palestra sobre recursos oferecidos pelo DB2, porm iremos priorizar nestes artigos os recursos e as sintaxes que sejam padro ANSI SQL, ou seja, que esto ou deveriam estar disponveis em qualquer sistema gerenciador de bancos de dados (SGBD). Neste artigo, vamos falar do uso dos seguintes recursos SQL: Vises; Consultas aninhadas na clusula WHERE; Consultas aninhadas na clusula FROM; Consultas aninhadas na clusula SELECT. Na teoria de banco de dados, uma viso (view) consiste de uma consulta armazenada acessvel como uma tabela virtual em um banco de dados relacional ou um conjunto de documentos em um banco de dados orientado a documentos, composto pelo conjunto de resultados de uma consulta. Ao contrrio de tabelas comuns (tabelas base) em um banco de dados relacional, uma viso no faz parte do esquema fsico: uma tabela virtual dinmica computada a partir de dados no banco de dados. Alterar os dados em uma tabela altera os dados mostrados nas invocaes subsequentes da viso. Em alguns bancos de dados NoSQL as vises so a nica forma de consulta a dados. Vises podem oferecer vantagens sobre tabelas nos seguintes aspectos: Vises podem representar apenas um subconjunto dos dados contidos em uma tabela; Vises podem juntar e simplificar vrias tabelas em uma tabela virtual nica; Vises podem funcionar como tabelas agregadas, atravs dos mecanismos de agregao do banco de dados (sum, average, etc.) e apresenta os resultados calculados como parte dos dados; Vises podem esconder a complexidade dos dados, por exemplo, uma viso poderia se chamar Vendas2000 ou Vendas2001, particionando transparentemente a tabela bsica real; Vises ocupam muito pouco espao de armazenamento, o banco de dados contm apenas a definio de uma viso e no uma cpia de todos os dados que ele apresenta; Dependendo do SGBD utilizado, vises podem fornecer a segurana extra; Vises podem limitar o grau de exposio de uma ou mais tabelas para o mundo exterior. Assim como funes (function, na programao) podem fornecer abstrao, usurios do banco de dados podem criar abstraes usando vises. Em outro paralelo com as funes, os usurios do banco de dados podem manipular vises aninhadas, assim, uma viso pode agregar dados de outras vises. Sem o uso de vises a normalizao de bases de dados alm da segunda forma normal se tornaria muito mais difcil. Vises podem tornar mais fcil a
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 2/14
8/4/2014
criao de junes sem perdas de decomposio. Assim como as linhas em uma tabela base no tm qualquer ordem definida, as linhas disponveis atravs de uma viso no aparecem com qualquer classificao padro. A viso uma tabela relacional e o modelo relacional define uma tabela como um conjunto de linhas. Uma vez que as tabelas no so ordenadas - por definio - as linhas de uma viso tambm no so ordenadas. Portanto, uma clusula ORDER BY na definio de exibio no tem sentido. O padro SQL ANSI 2003 no permite que uma clusula ORDER BY em uma consulta SQL na instruo CREATE VIEW, assim como no permitida na instruo CREATE TABLE. No entanto, dados ordenados podem ser obtidos a partir de uma viso, da mesma forma como qualquer outra tabela - como parte de uma instruo de consulta. No entanto, alguns SGBDs (como Oracle e SQL Server) permitem uma viso a ser criada com uma clusula ORDER BY em uma subquery, afetando como os dados so exibidos. Em uma consulta SQL ao banco de dados, uma subconsulta (consulta aninhada dentro de outra consulta) uma consulta que utiliza os valores da consulta externa em sua clusula WHERE. A subconsulta avaliada uma vez para cada linha processada pela consulta externa. Voc pode usar uma subconsulta para os seguintes fins: Definir um conjunto de linhas que precisam ser inseridos em uma tabela; Definir um conjunto de resultados que ser usado para criao de uma viso; Definir um ou mais valores de uma instruo de atualizao (UPDATE); Fornecimento de valores para as clusulas WHERE, HAVING e START WITH para instrues SELECT, UPDATE e DELETE.
Vises
As vises (do ingls views) so talvez os objetos mais comuns nos bancos de dados, mais at
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 3/14
8/4/2014
do que as prprias tabelas. De certo modo, as vises so tabelas virtuais, ou seja, elas se parecem com tabelas, mas as vises buscam dados que esto fisicamente armazenados em uma ou mais tabelas. Para o usurio, as vises se parecem tanto com as tabelas que fica difcil dizer com qual objeto se est trabalhando. J para os administradores de bancos de dados (DBAs), as vises so um excelente recurso para gerenciamento da segurana dos dados. Afinal, elas so objetos que funcionam somente para leitura, ou em outras palavras, no se consegue alterar dados atravs de vises (existem tipos especiais de vises que so exceo, mas no sero discutidas aqui). Alm disso, o administrador pode criar vises de modo a restringir o acesso apenas a determinados campos da tabela, impedindo por exemplo a leitura de campos especiais. Portanto, se voc no o DBA do banco de dados com o qual costuma trabalhar, provavelmente voc j acessou vises pensando que lia tabelas. As vises funcionam como declaraes de SELECT precompiladas, que so executadas quando o objeto correspondente solicitado. Virtualmente, qualquer SELECT pode ser salvo como viso. Basta para isso usar a sintaxe CREATE VIEW nome AS, seguida da declarao em questo. Uma exceo importante que as vises no aceitam a clusula ORDER BY. At existem recursos para se burlar esta limitao, mas a entramos no terreno das famosas gambiarras. O melhor mesmo respeitar o limite, a menos que seja realmente necessrio. Outra situao muito comum de uso de vises a de guardar de uma maneira simples consultas e/ou subconsultas que so executadas com muita frequncia. Esta abordagem interessante porque pode simplificar bastante o trabalho dos desenvolvedores, reduzindo a complexidade das declaraes SQL. Vamos ver um exemplo. Digamos que uma consulta muito frequente no nosso banco de dados seja a identificao do ranking de produtos mais vendidos no ms anterior. Esta consulta usada para uma srie de relatrios e, para no termos que reescrev-la em todos os relatrios, vamos trat-la como uma viso. Primeiramente vamos definir esta viso. Precisamos criar uma consulta de agregao que calcule a demanda por produto ocorrida no ms passado. Para isso, vamos precisar das tabelas de demanda e de produto (veja na Figura 1). Usaremos a funo de agregao SUM() para totalizar a demanda e agruparemos os dados por produtos. Para tornar a viso mais til, importante incluir o cdigo dos produtos, uma vez que todas as junes com outras tabelas e/ou vises sero feitas atravs destes cdigos. Como as vises no consideram ordenao de dados (e nem devem faz-lo), vamos esquecer a questo do ranking e apresentar apenas a demanda de cada produto. Para filtrar as datas, precisamos definir algo que seja genrico, do contrrio vamos ter que criar uma nova viso a cada mudana do ms. Existem muitas maneiras de se criar este filtro e cada SGBD traz seus prprios registros e funes para trabalhar com datas. (Veja informaes adicionais a este respeito na seo LEITURA RECOMANDADA). Eu preferi construir este filtro usando recursos o mais prximos possveis do padro ANSI SQL, ento usamos funes escalares como MONTH(), YEAR(), RIGHT() e a funo CAST(), que usada para converso de tipos de dados. Usaremos tambm o registro especial CURRENT_TIMESTAMP, que retorna a hora atual do sistema com preciso de (pelo menos) milissegundos, alm de estar implementado numa grande variedade de SGDBs relacionais, como DB2, ORACLE, SQL SERVER, FIREBIRD e POSTGRES. A ideia selecionar datas que estejam entre o dia 1 e o ltimo dia do ms anterior. Como no muito simples identificar o ltimo dia de cada ms, fica mais fcil dizer que a data
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 4/14
8/4/2014
desejada tem que ser maior ou igual ao 1 dia do ms anterior e menor do que o 1 dia do ms atual. Algo do tipo "Data >= 01/MesAnterior AND Data < 01/MesAtual". Usando as funes e registros de sistema citados acima, o filtro de datas ficar parecido com o apresentado na Listagem 1.
Listagem 1. Parametrizao do filtro de datas do ms anterior.
D a t a> =C A S T ( Y E A R ( C U R R E N T _ T I M E S T A M P )A SV A R C H A R )-a n o + R I G H T ( ' 0 ' + C A S T ( ( M O N T H ( C U R R E N T _ T I M E S T A M P ) 1 )A SV A R C H A R ) , 2 )-m e s +' 0 1 '-d i a A N D D a t a<C A S T ( Y E A R ( C U R R E N T _ T I M E S T A M P )A SV A R C H A R )-a n o +R I G H T ( ' 0 ' + C A S T ( ( M O N T H ( C U R R E N T _ T I M E S T A M P ) )A SV A R C H A R ) , 2 )-m e s+' 0 1 '-d i a
O leitor mais atento vai observar que a lgica da Listagem 1 tem uma falha: no funciona durante o ms de Janeiro. Na realidade, este problema com datas mais fcil de se resolver usando funes definidas pelo usurio (ou UDF), pois vai facilitar inclusive o entendimento da declarao SQL, j que esta lgica vai estar encapsulada numa funo. Porm as UDFs sero estudadas apenas no prximo artigo da srie. Por isso voltaremos a esta questo quando tratarmos do assunto. Por hora, vamos considerar que esta soluo adequada. Colocando tudo para funcionar e definindo a consulta como uma viso, temos o SQL apresentado na Listagem 2.
Listagem 2. Criao da viso com demanda por produto no ms anterior.
C R E A T EV I E Wv w D e m a n d a P r o d u t o M e s P a s s a d oA S S E L E C TP . p k P r o d u t o ,P . P r o d u t o ,S U M ( T . V a l o r R e a l )A SD e m a n d a F R O Mt b l D e m a n d aT I N N E RJ O I Nt b l P r o d u t oPO NT . f k P r o d u t o=P . p k P r o d u t o W H E R ET . D a t a> =C A S T ( Y E A R ( C U R R E N T _ T I M E S T A M P )A SV A R C H A R ) +R I G H T ( ' 0 ' + C A S T ( M O N T H ( C U R R E N T _ T I M E S T A M P )-1A SV A R C H A R ) ,2 ) +' 0 1 ' A N DT . D a t a<C A S T ( Y E A R ( C U R R E N T _ T I M E S T A M P )A SV A R C H A R ) +R I G H T ( ' 0 ' + C A S T ( M O N T H ( C U R R E N T _ T I M E S T A M P )A SV A R C H A R ),2 ) +' 0 1 ' G R O U PB YP . p k P r o d u t o ,P . P r o d u t o ;
A sentena da Listagem 2 para definio de uma viso pode ser executada em diferentes SGBDs, uma vez que usamos recursos padro ANSI SQL. Agora vamos usar esta viso na gerao de um relatrio simples: ranking com os 10 produtos mais vendidos no ms anterior. Como a viso j traz estas informaes, basta fazermos a ordenao dos dados e apresentarmos apenas os 10 primeiros registros. Porm, como comentamos no artigo anterior, cada SGBD usa um recurso diferente para fazer esta exibio. A Listagem 3 mostra a declarao SQL deste relatrio no DB2. No SQL SERVER, a mudana seria pequena, j que teramos que usar o SELECT TOP para esta seleo (veja Listagem 4).
Listagem 3. Sintaxe do DB2 para apresentao dos produtos mais vendidos.
S E L E C TP r o d u t o ,D e m a n d a F R O Mv w D e m a n d a P r o d u t o M e s P a s s a d o O R D E RB YD e m a n d aD E S C F E T C HF I R S T1 0R O W SO N L Y
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
5/14
8/4/2014
Listagem 4. Sintaxe do SQL Server para apresentao dos produtos mais vendidos.
S E L E C TT O P1 0P r o d u t o ,D e m a n d a F R O Mv w D e m a n d a P r o d u t o M e s P a s s a d o O R D E RB YD e m a n d aD E S C
Como as consultas mostradas nas Listagens 3 e 4 fazem a mesma coisa (s que em SGBDs diferentes), o resultado obviamente ser idntico, como vemos na Tabela 1. Existem vises que usam recursos especiais para melhorar a performance, por exemplo, no caso de vises que manipulam grandes volumes de dados. Estas vises costumam combinar a gravao de dados (fisicamente) num objeto especial, separado das tabelas fonte, e criar uma estratgia de indexao destes dados. O nome deste tipo de viso varia conforme o fornecedor do SGBD, mas as estratgias de melhoria de performance so parecidas: no DB2, elas so chamadas de Materialized Query Tables, no ORACLE so Materialized Views e no SQL SERVER so Indexed Views. A sintaxe de implementao destas vises varia conforme o SGBD e por esta razo no iremos nos estender neste assunto. O leitor interessado pode consultar os links apresentados na seo REFERNCIAS.
8/4/2014
na Figura 1 que precisaremos das tabelas de demanda, brick e cidade (j que a tabela de demanda no tem dados por cidade e sim por brick, como explicamos no ltimo artigo). A entra o problema: no queremos TODA demanda ocorrida nestas cidades, mas sim s a demanda dos trs produtos mais vendidos. Identificar estes produtos fcil, basta usar a viso vwDemandaProdutoMesPassado que criamos anteriormente e ela nos retorna a lista de cdigos de produto desejados. O que precisamos fazer usar esta lista como um novo filtro na clusula WHERE (veja Listagem 5).
Listagem 5. Usando consulta aninhada para filtrar produtos com maior demanda.
S E L E C TC . C i d a d e ,S U M ( T . V a l o r R e a l )A SD e m a n d a F R O Mt b l D e m a n d aT I N N E RJ O I Nt b l B r i c kBO NT . f k B r i c k=B . p k B r i c k I N N E RJ O I Nt b l C i d a d eCO NB . f k C i d a d e=C . p k C i d a d e W H E R ET . D a t a=' 2 0 1 0 1 2 2 4 ' A N DT . f k P r o d u t oI N( S E L E C Tp k P r o d u t o F R O Mv w D e m a n d a P r o d u t o M e s P a s s a d o O R D E RB YD e m a n d aD E S C F E T C HF I R S T3R O W SO N L Y ) G R O U PB YC . C i d a d e O R D E RB Y1
Como se v na Listagem 5, temos uma consulta dentro da outra, mas muito fcil identificlas. Eu usei a sintaxe do DB2 para seleo dos 3 melhores produtos (FETCH FIRST n ROWS ONLY), mas a converso desta sintaxe para outros SGBDs bastante simples, como mostramos no primeiro artigo da srie. Vamos a outro exemplo. No primeiro artigo da srie, mostramos uma consulta SQL para criao de um relatrio de demanda dos produtos Eupressin Cpr 20 Mg X 30 e o Norvasc Cpr 10 Mg X 30 por estado da regio Sul no primeiro trimestre de 2011. Observe que temos trs filtros, um para as datas do 1 trimestre/2011, outro para os produtos Eupressin Cpr 20 Mg X 30 e o Norvasc Cpr 10 Mg X 30 e o terceiro que queremos um relatrio de demanda por Estado, mas s aqueles que pertencem regio Sul. Como explicamos anteriormente, precisaremos de seis tabelas (veja Figura 1): de demanda, produtos, bricks, cidades, estados e regies. Na clusula SELECT, precisamos apenas dos campos Estado, Produto e da somatria da demanda. Mas existe um detalhe interessante neste relatrio que no apresentamos naquela oportunidade. Como o relatrio deve exibir um agrupamento por estado e por produto, precisamos destas duas tabelas como parte da clusula FROM. Mas no precisamos da tabela de regies ali, porque esta tabela s usada para filtro e no na clusula SELECT. Portanto, este um exemplo perfeito de quando podemos substituir junes por consultas aninhadas e obter um resultado mais eficaz. Esta declarao mostrada na Listagem 6.
Listagem 6. Demanda por estado, usando consultas aninhadas.
S E L E C TE . E s t a d o ,P . P r o d u t o ,S U M ( T . V a l o r R e a l )A SD e m a n d a F R O Mt b l D e m a n d aT I N N E RJ O I Nt b l B r i c kBO NT . f k B r i c k=B . p k B r i c k I N N E RJ O I Nt b l C i d a d eCO NB . f k C i d a d e=C . p k C i d a d e I N N E RJ O I Nt b l E s t a d oEO NC . f k E s t a d o=E . p k E s t a d o I N N E RJ O I Nt b l P r o d u t oPO NT . f k P r o d u t o=P . p k P r o d u t o W H E R ET . D a t aB E T W E E N' 2 0 1 1 0 1 0 1 'A N D' 2 0 1 1 0 3 3 1 ' A N DE . f k R e g i a o=( S E L E C TR . p k R e g i a o
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
7/14
8/4/2014
Com um pouco de ateno, muito fcil entender o que faz a consulta da Listagem 7. A sintaxe clara, as informaes esto todas no lugar certo e a declarao em si razoavelmente simples (ou curta, se preferir). Veja que usamos a viso vwDemandaProdutoMesPassado duas vezes na clusula FROM,
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 8/14
8/4/2014
uma diretamente e a segunda como parte de um subconsulta. Agora imagine como ficaria esta declarao (Listagem 7) se ns no tivssemos criado esta viso (veja novamente a Listagem 2)! A simplicidade e facilidade de leitura que mencionamos seriam totalmente perdidas. Esta consulta ilustra bem o uso de consultas aninhadas na clusula FROM, mas esta no a nica maneira de escrev-la. Existem outras estratgias para se criar este relatrio e voltaremos a falar deste exemplo ao longo desta srie de artigos.
Note que a Listagem 8 traz duas consultas aninhadas, uma na clusula FROM, que j usamos na Listagem 7, mais a nova subconsulta na clusula SELECT. Observe tambm que esta subconsulta usa um filtro, comparando o valor de demanda do registro da consulta aninhada, identificado com o apelido X, com o valor do registro atual da consulta externa, identificado
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194 9/14
8/4/2014
com o apelido S. Esta comparao quem garante a contagem correta dos registros, identificando assim a ordenao que desejamos. Mas lembre-se: a contagem, isto , a subconsulta, repetida para cada registro da consulta externa. Esta tcnica de ranqueamento antiga, usada com recursos padro ANSI SQL-92. Atualmente temos outros recursos para conseguir estes resultados. Mas, como voc j deve ter desconfiado, voltaremos a falar desta questo num dos prximos artigos desta srie. Um segundo exemplo: relatrio para calcular saldo em estoque. Para este exemplo, vamos usar uma tabela especial: a tabela de movimentos de estoque, definida na Listagem 9, onde os valores positivos indicam entradas no estoque e os valores negativos so as sadas do estoque.
Listagem 9. Criao da tabela de Movimento de Estoque
C R E A T ET A B L Ep r o d . t b l M o v t o E s t o q u e( f k P r o d u t oI N T D a t a Q t d N O TN U L L ,
I D A T EN O TN U L L , I N T N O TN U L L ,
C O N S T R A I N Tp k M o v t o E s t o q u eP R I M A R YK E Y( f k P r o d u t o ,D a t a ) ) ;
I N S E R TI N T Op r o d . t b l M o v t o E s t o q u eV A L U E S ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 1 ' ,1 0 0 0 ) , ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 2 ' ,1 0 0 ) , ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 3 ' ,1 5 0 ) , ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 4 ' ,2 0 0 ) , ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 5 ' ,5 0 ) , ( 2 2 1 7 2 0 ,' 2 0 1 0 0 1 0 6 ' ,1 0 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 0 5 ' ,1 0 0 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 0 6 ' ,8 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 0 7 ' ,1 5 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 0 8 ' ,2 5 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 0 9 ' ,5 0 0 ) , ( 5 7 8 8 4 0 ,' 2 0 1 0 0 1 1 0 ' ,3 5 0 ) ;
Como a inteno calcular o saldo dirio por produto, a consulta precisa identificar todas as entradas e sadas de cada produto at a data em questo. E no podemos esquecer que os dados precisam obrigatoriamente estar ordenados na forma desejada. Considerando tudo isso, usamos uma consulta aninhada que calcula a coluna Saldo, como se v na declarao SQL da Listagem 10. A seguir, temos o resultado desta consulta na Tabela 4, em que destacamos em negrito as linhas que identificam o incio do balano para cada produto.
Listagem 10. Saldo em Estoque por Produto
S E L E C Tf k P r o d u t o ,D a t a ,Q t d ,( S E L E C TS U M ( Q t d ) F R O Mp r o d . t b l M o v t o E s t o q u eS W H E R ES . f k P r o d u t o=T . f k P r o d u t o A N DS . D a t a< =T . D a t a )A SS a l d o F R O Mp r o d . t b l M o v t o E s t o q u eT O R D E RB Y1 ,2 ;
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
10/14
8/4/2014
De maneira geral, quando voc imaginar que precisa usar consultas aninhadas na clusula SELECT, fique atento a trs condies: se sua subconsulta precisa mesmo interagir com os registros da consulta externa; atendida a condio anterior, verifique se esta subconsulta pode ou no ser substituda por uma juno de tabelas; se passar nos dois primeiros testes, fique atento com o nmero de registros retornados pela consulta externa. Lembre-se que uma consulta aninhada na clusula SELECT ser executada para cada registro retornado pela consulta externa. Ento imagine, por exemplo, uma consulta que retorne 10.000 registros. Mesmo que o otimizador de consultas do seu SGBD seja muito bom, muito provvel que esta consulta cause impacto significativo no seu servidor!
8/4/2014
consultas. No primeiro caso, faremos a consulta usando parmetros fixos (ou escalares se preferir). A Listagem 11 mostra esta declarao. Esta consulta no deve ser salva como uma viso, j que ela traz datas fixas. Mas este exemplo ilustra bem a questo de performance. Veja na Figura 2 o plano de execuo e no destaque o custo estimado desta rvore, que de 0,865938. No segundo teste, vamos considerar a verso parametrizada que usamos inicialmente, fazendo uso do registro de sistema CURRENT_TIMESTAMP e outras funes padro ANSI SQL, apresentadas novamente na Listagem 12. Note que a consulta da Listagem 12 sempre busca dados do ms anterior ao ms corrente e isso que precisamos.
Ela at parece um pouco complexa, mas no final das contas estamos comparando os valores do campo DATA com dois valores calculados. Note na Figura 3 que o plano de execuo bastante parecido com o da Figura 2, apesar dela ter um custo bem maior: 1,77682 (105% maior que o custo da primeira consulta). Mas claro que o filtro usado no a nica opo de parametrizao. No prximo teste, filtramos os dados comparando o ms e o ano de cada registro. Parece uma melhoria, j que a lgica do filtro bem mais simples, como se v na Listagem 13.
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
12/14
8/4/2014
Esta aparente simplicidade terrivelmente enganosa, porque aqui fazemos duas operaes para cada registro: calcular o ms e o ano do campo DATA. Considerando que a tabela grande (mais de 2 milhes de registros), esta operao certamente vai ter um custo alto. E de fato isso que acontece, pois o custo total de execuo desta rvore sobe para 9,94425 (veja no quadro em destaque da Figura 4)! Este nmero 5,5 vezes maior do que o custo da consulta anterior e 11,5 vezes maior que a consulta com datas fixas. Para concluir esta seo, apresentamos a compilao de todos os testes na Tabela 5.
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
13/14
8/4/2014
Pode parecer redundante este comentrio, mas a importncia do tema o permite: sempre tome cuidado com as declaraes SQL que escreve. Pequenas alteraes podem ter grandes impactos em matria de performance!
Concluso
Vimos aqui como criar e usar vises e como lidar com consultas aninhadas. Estes so recursos muito poderosos e que esto disponveis h muito tempo. Mas eles ampliam em muito a gama de relatrios que podemos criar com declaraes SQL e o leitor interessado precisa aprender a us-los corretamente. No prximo artigo, vamos estudar recursos programveis da linguagem SQL, como funes definidas pelo usurio (UDFs), discutindo tanto as funes escalares como as tabulares. Espero que tenha gostado das informaes apresentadas. At breve!
Wagner Crivelini
Engenheiro formado pela UNICAMP, consultor em TI com 15 anos de experincia, particularmente em projetos de Business Intelligence. Atualmente trabalha na IBM, onde atua como DBA em projeto internacional.
http://www.devmedia.com.br/websys.5/webreader_print.asp?cat=2&artigo=4194&revista=impressao_95#a-4194
14/14