varlena
varlena

By A. Elein Mustain
Traduzidos por Pedro B.
General Bits 11-July-2004 Edições: 79

Arquivos
General Tidbits

General Bits é uma coluna baseada na lista de discussão do PostgreSQL pgsql-general.
Para saber mais sobre a lista de discussão pgsql-general e sobre o PostgreSQL, procure em http://www.postgresql.org/.
Castellano
Português
Brasilian-Português

7.4 Documentation
Google General Bits

Speaking Engagements

July 26-30, 2004
O'Reilly Open Source Conference
Tutorial: Introduction to PostgreSQL

Notícias

PostgreSQL
Consulting, Support & Training

Para receber um aviso via email sobre as novas edições do General Bits, envie um email para Elein.

Assinaturas



Configurando tamanhos de Free Space Map
Re: Index Problem? 16-Apr-2004

As duas variáveis de Global User Configuration, max_fsm_pages e max_fsm_relations são um pouco misteriosas. Mas configurando estes valores de Free Space Mapping values poderá ajudar as suas queries a serem executadas mas rapidamente e mais eficientemente com uma mais eficiente gestão de memória. Para ajudá-lo a compreender estas variáveis pode usar VACUUM VERBOSE para lhe dizer o que acha necessário e qual a configuração corrente. No fim do VACUUM VERBOSE deverá ver:

   INFO: free space map: 136 relations, 25014 pages stored; 22608 total pages needed
   DETAIL: Allocated FSM size: 1000 relations + 20000 pages = 178 kB shared memory.
A secção INFO diz-lhe o que o servidor irá usar e o que é necessário. A secção DETAIL diz-lhe como tem as variáveis GUC configuradas.

É recomendado que configure max_fsm_pages e max_fsm_relations um pouco maior que o valor indicado em INFO. No exemplo acima, mudando max_fsm_pages de 20000 para 40000 diminuiu o tempo necessário para uma query má em cerca de 30%. Mas como sempre, configurar coisas muito alto tem um preço. Tenha cuidado.

Para modificar max_fsm_pages e max_fsm_relations edite o ficheiro $PGDATA/postgresql.conf e reinicie (start e stop) o servidor.

Contribuições: Ron St-Pierre rstpierre at syscor.com, Josh Berkus josh at agliodbs.com, Tom Lane tgl at sss.pgh.pa.us, mr_bubbs at #postgresql
Novo e melhorado PL/Perl
PL/Perl with Rows, Sets and Stored Memory 11-July-2004

A versão7.5 release incluirá o novo e melhorado plperl. As extensões para plperl nesta versão irão incluir a possibilidade de escrever funções de trigger, fazer queries à base de dados, retornar sets e linhas e sets de rows assim como guardar dados locais à conecção.

Na Edição #78 falámos de funções de trigger e queries à base de dados. Nesta edição exemplos mostrarão como retornar linhas, sets de linhas e como guardar dados através de chamadas de função.

Retornar Linhas

Para retornar uma linha numa função de PlPerl, simplesmente retorne um hash descrevendo essa linha. Muito simples. Neste exemplo, iremos modificar a função mmav() da Edição #78 criando um tipo chamado mmav e depois mudando apenas duas linhas da função original. As linhas modificadas são a definição de tipo de retorno e a chamada a retornar.
   create type mmav ( min integer, max integer, avg float );
   create or replace function mmav(text,text )
   returns mmav as
   '
   my $tble = $_[0];
   my $col  = $_[1];
   my $qry  = ''select ''.$col.'' from ''.$tble;
   my $min  = 0;
   my $max  = 0;
   my $sum  = 0;

   my $rv = spi_exec_query( $qry );
   if (@{$rv->{rows}} == 0 ) { return NULL };
   for ( my $i=0; $i < @{$rv->{rows}} ; $i++ ) {
      if ( $i == 0 ) {
         $sum = $max = $min = $rv->{rows}[$i]->{$col};
         next;
      }
      if ( $max < $rv->{rows}[$i]->{$col} )
         { $max = $rv->{rows}[$i]->{$col}; }
      if ( $min > $rv->{rows}[$i]->{$col} )
         { $min = $rv->{rows}[$i]->{$col}; }
      $sum += $rv->{rows}[$i]->{$col};
   }
   return (min => $min, max => $max, avg=>$sum/@{$rv->{rows}};

   ' language 'plperl';

Retornar Sets de Linhas

Para retornar sets de linhas em PlPerl, pode retornar um array de hashes. Terá de construir o array e depois retornar todo o array por refer&etilde;ncia. Este procedimento é diferente do plpgsql onde se retorna uma linha de cada vez em ciclo usando RETURN NEXT;

Neste exemplo, temos uma tabela de jogos de rugby. A tabela contém (team1 text, team2 text, score1 integer, score2 integer) mostrando as duas equipas que jogaram e os seus resultados. O que queremos é saber a média de pontos para cada equipa. Isto é ligeiramente complexo por as equipas poderem estar em qualquer uma das colunas team1 ou team2 e não queremos rever toda a tabela duas vezes. Hashes são bons para este tipo de coisas.

Usamos um hash para somar e contar os pontos e depois usamos as keys desse hash para gerar o array de hashes que queremos retornar. E claro, definimos o type de linha antes da função.

Note que neste exemplo estamos a usar quoting com dólar que também estará disponível na versão 7.5. Isto permite-lhe configurar os caracteres de quoting à sua escolha. Mais neste assunto será escrito noutra edição, no entanto, com PlPerl, esta funcionalidae é particularmente vantajosa.

create type team_avg AS ( team text, avg_score float );

create or replace function team_avg()
returns team_avg as
$$
my %ta;
my $avg;
my @rows;
my @teams;
my $qry = 'select team1, score1, team2, score2 from tmatches';
my $rv = spi_exec_query ($qry );

   for ( my $i=0; $i < @{$rv->{rows}} ; $i++ ) {
      $ta{ $rv->{rows}[$i]->{'team1'} }{'score'} +=  $rv->{rows}[$i]->{'score1'};
      $ta{ $rv->{rows}[$i]->{'team1'} }{'gcount'} +=  1;
      $ta{ $rv->{rows}[$i]->{'team2'} }{'score'} += $rv->{rows}[$i]->{'score2'};
      $ta{ $rv->{rows}[$i]->{'team2'} }{'gcount'} +=  1;
   }
   @teams = keys %ta;
   for ( my $i=0 ; $i < @teams ; $i++) {
      push @rows, { 'team'=>$teams[$i],
         'avg_score'=>$ta{$teams[$i]}{'gcount'} == 0 ? 0 : \
            $ta{$teams[$i]}{'score'}/$ta{$teams[$i]}{'gcount'} };

   }
   return \@rows;
$$
language 'plperl';
select sname, avg_score from teams t, team_avg() a where t.sname=a.team;

Usando Global Memory

PlPerl dá-lhe acesso a um hash sharado que é local à conecção. Isto pode dar muito jeito para guardar valores específicos da conecção. Por examplo, as seguintes duas linhas vão buscar e põr hashes arbitrários no hash sharado.

create or replace function put_conn_values (text, text)
returns void as
$$
   $_SHARED{$_[0]}=$_[1];

$$ language 'plperl';

create or replace function get_conn_values (text)
returns text as
$$
   return $_SHARED{$_[0]};

$$ language 'plperl';

select put_conn_values( 'user','jane');
select get_conn_values( 'user');

Alguns factores a ter em consideração acerca desta funcionalidade são que a memória não será libertada até que a conecção o seja também. E se voc&etilde; executar uma função que escreve vários valores várias vezes na mesma conecção, os valores em $_SHARED serão serão sobrepostos pela última função que determina os valores. Isto não é problema com este exemplo. No entanto, usando o hash $_SHARED para agregados, onde a função agregada é usada mais do que uma vez numa instrução, irá causar confusão. As duas invocações serão escritas para os mesmos baldes. O código para estes exemplos poe ser encontrado aqui.

Editor: elein at varlena.com andrew at dunslane.net david at fetter.org


Comentários e Correções são bem vindos. Sugestões e contribuições de itens também são bem vindos. Envie-os!
Copyright A. Elein Mustain 2003, 2004, 2005
Traduzidos por Pedro B.

Google
Search General Bits & varlena.com Search WWW