|
|||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
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.
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 LinhasPara 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 LinhasPara 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 MemoryPlPerl 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.
|
||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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. |