AE    
Por A. Elein Mustain
Traduzidos por Juliano da Silva Ignacio
General Bits 9-Jun-2003 Edição: 29

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/.
Arquivos
General Tidbits
Artigos Português
Google General Bits
Notícias
Para receber um aviso via email sobre as novas edições do General Bits, envie um email para Elein.
ae Consulting PostgreSQL Design & Implementation
Assinaturas Support General Bits
pghostger.com
OSCON Speaker
 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Nesta Edição
Nesta Edição 08/Junho/2003

Esta edição contém diversos artigos interessantes como contribuição de algumas pessoas muito prestativas. Devido à (felizes) obrigações familiares, meu próprio tempo na semana passada foi muito limitado.

Acho que terei este mesmo dilema para a edição de 14 de Julho, porque planejo estar assistindo a (e discursando na) Conferência sobre Open Source da editora O'Reilly na semana anterior à esta edição. Sugestões sobre conteúdo são sempre bem vindas, mas são especialmente bem vindas para esta edição. Sugestões para esta edição serão válidas se enviadas até 4 de Julho.

Muito obrigada especialmente para Sean Chittenden, Rao Kumar e ao Grupo de Usuários do PostgreSQL de São Francisco, e à você por sua paciência.

Editor: elein em varlena.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Testando o limite (overhead) de chamadas de funções
por Sean Chittenden 30/Mai/2003

Para avaliar o limite de chamadas de funções em plpgsql e C, Sean Chittenden escreveu as funções abaixo. As funções rodaram em um laptop PIII de 600MHz. Em todas as vezes há uma média de 50 chamadas para uma função e o tempo decorrido é mostrado pelo EXPLAIN ANALYZE. A primeira função compara uma função em plpgsql e outra em C compatível.

	/* código pl/pgsql INÍCIO */
	CREATE OR REPLACE FUNCTION t1() RETURNS INT AS '
	DECLARE
		v_i INT;
	BEGIN
		v_i := 1;
		RETURN v_i;
	END;
	' LANGUAGE 'plpgsql';
	
	CREATE OR REPLACE FUNCTION t2() RETURNS INT AS '
	DECLARE
		v_i INT;
	BEGIN
		SELECT 1 INTO v_i;
		RETURN v_i;
	END;
	' LANGUAGE 'plpgsql';
	
	CREATE OR REPLACE FUNCTION t3() RETURNS INT AS '/tmp/t3.so' LANGUAGE C;
	/* Fim */
	
	Onde t3() é definido como:
	
	/* Início */
	#include "executor/spi.h"
	int t3(void);
	int t3(void) {
		int v_i;
		v_i = 1;
		return(v_i);
	}
	/* Fim */

Estes testes são intencionalmente bem básicos. Eles todos poderiam somente retornar 1. Mas a tarefa é o que conta, mesmo que embora a versão em C seja otimizada para somente retornar(1). Esta é a vantagem de possuir um compilador real trabalhando para você. Para o primeiro teste de chamada, uma nova conexão é iniciada para todas interações. Carregar antecipadamente não faz qualquer diferença entre, se as bibliotecas foram carregadas ou não.

Neste conjunto de resultados, a Primeira chamada(1) está com plpgsql.so carregado antecipadamente. A Primeira chamada(2) não tem o plpgsql.so carregado antecipadamente (novo recurso em pre-7.4).

	 Função    |  Primeira       |  Primeira       |  Chamadas 
                    |  chamada(1)     |  chamada(2)     |  Subsequentes
	-----------+-----------------+-----------------+-------------------
	 t1()      |  2.35msec       |  3.34msec       |  0.24msec
	 t2()      |  2.46msec       |  3.45msec       |  0.28msec
	 t3()      |  0.37msec       |  0.75msec       |  0.16msec

Estes resultados não são o que interessa, mas nos mostra qual é o limite para chamadas de função em várias circunstâncias. Aqui está um conjunto de testes muito mais interessantes, no entanto, com t(4..6):

	CREATE OR REPLACE FUNCTION t4() RETURNS INT AS '
	DECLARE
		v_i INT;
		ret INT;
	BEGIN
		FOR v_i IN 1..1000 LOOP
			ret := v_i;
		END LOOP;
		RETURN ret;
	END;
	' LANGUAGE 'plpgsql';
	
	CREATE OR REPLACE FUNCTION t5() RETURNS INT AS '
	DECLARE
		v_i INT;
		ret INT;
	BEGIN
		FOR v_i IN 1..1000 LOOP
			SELECT v_i INTO ret;
		END LOOP;
		RETURN ret;
	END;
	' LANGUAGE 'plpgsql';
	
	CREATE OR REPLACE FUNCTION t6() RETURNS INT AS '/tmp/t6.so' LANGUAGE C;
	
	/* Início C/t6() */
	#include "executor/spi.h"
	int t6(void);
	int t6(void) {
		int v_i;
		int ret;
	
		for (v_i = 0; v_i < 1000; v_i++)
			ret = v_i;
		return(ret);
	}
	/* Fim C */

Aqui a diferença começa a aparecer. t5() usa SELECT INTO ao invés de :=. Toda vez que um SELECT INTO é utilizado, ele tem que dizer para o backend (processo em segundo plano) para configurar um plano de consulta, embora no plpgsql, os planos estejam em cache. Nada chega perto de C... não é surpresa conseguir 1.000 interações extras.

	 Função    |  Primeira       |  Primeira       |  Chamadas 
                    |  chamada(1)     |  chamada(2)     |  Subsequentes
	-----------+-----------------+-----------------+-------------------
	 t4()      |   6.16msec      |   9.17msec      |   3.54msec
	 t5()      |  34.52msec      |  41.18msec      |  29.19msec
	 t6()      |   0.37msec      |   0.77msec      |   0.16msec

O exemplo em C não executa consultas, mas isto não foi necessário para os testes apresentados. Percorrer registros está limitado pela E/S e o HD do laptop não tem a qualidade de um utilizado em servidor, então, funções matemáticas puras foram mais apropriadas para este nível de teste. O pl/pgsql tem o péssimo hábito de copiar dados com ROWTYPEs/RECORDs, uma vez que em C você pode usar um buffer de tamanho fixo e somente realloc()[ar] o espaço.

Colaboradores: Sean Chittenden sean em chittenden.org

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Utilitário para pgsession
Por Rao Kumar raokumar@netwolves.com 28/Mai/2003

Em anexo está um utilitário para listar e terminar sessões do PostgreSQL. Este script irá funcionar com versões 7.2 ou superior. Este script usa kill -TERM, e não kill -9 para terminar as sessões.

	Script:  pgsession
		pgsession : Lista/Termina sessões de usuários no banco de dados 

	Sintaxe:
		pgsession [OPÇÃO]... [USUÁRIO]

	Opções:
		--h (help)  mostra estas informações de ajuda, e sai 
		-l  (list)  lista as sessões do banco de dados 
		-k  (kill)  termina (aborta) uma sessões do banco de dados 
		-f  (force) força terminar uma sessão (não pede confirmação, 
			   utilize em conjunto com a opção -k)
		-u  USUÁRIO especifica o nome do usuário do banco de dados 
		-p  PID     especifica o número do processo do usuário (pid)

Exemplos:
	  pgsession -l           lista todas as sessões
	  pgsession -l -u <user> lista as sessões do usuário
	  pgsession -k           termina todas as sessões
	  pgsession -k -f        força terminar todas as sessões
	  pgsession -k -u <user> terminar as sessões do usuário
	  pgsession -k -p <pid>  termina a sessão com um PID específico
Você pode baixar o script do pgsession na página do Tidbits.

Observação: uma lista das sessões e suas respectivas consultas está disponível também em psql utilizando:

	select * from pg_stat_activity; 

Colaboradores: Rao Kumar raokumar em netwolves.com

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tamanho da Página
[GENERAL] tamanho da página no postgresql 11/Mai/2003

Se na sua máquina, a função getpagesize() retorna 4096, isto significa que o tamanho da página para o postgresql é de 4096 bytes? A documentação para "Monitoring disk usage" (monitorando o uso do disco) diz que o tamanho da página do postgres é "geralmente" de 8KB (8192 bytes). Qual dos dois é o correto?

O tamanho da página do postgreSQL é determinado em tempo de compilação e, dado que a maioria das pessoas não mexem nisso, continuará sendo 8KB em 99.9% dos casos.

Colaboradores: sureshk2003 sureshk2003 em indiatimes.com, Martijn van Oosterhout kleptog em svana.org

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Obtendo uma capacidade extra em listas IN usando ODBC
[GENERAL] instrução "IN" causa cancelamento da execução? 22/Mai/2003

A consulta a seguir resultou em uma mensagem "Cancelled Execution" (execução cancelada) quando utilizada com ODBC no windows e quando a lista continha várias centenas de itens.

	select field1 from table where field2 in (lista);

O problema parece ser unicamente no driver ODBC. A consulta executa corretamente pelo psql e também funciona corretamente para muitas listas mais curtas. Duas maneiras de contornar este problema foram sugeridas.

A primeira sugestão cria uma instrução equivalente utilizando LIKE.

	SELECT field1 FROM table WHERE field2 IN (1,2,3,4,5,6,7);
	SELECT field1 FROM table WHERE ',1,2,3,4,5,6,7,' like '%,'||field2||',%';

A segunda maneira de contornar este problema é provavelmente mais rápida em tempo de execução. A sugestão está em colocar a lista em uma tabela, provavelmente uma tabela temporária, e alterar a consulta para executar uma junção com a tabela.

	select field1 from table t, listtable l where t.field2 = l.list_item;
Colaboradores: Andrew Ayers aayers em eldocomp.com, Mark Wilson mark em mediasculpt.com, Richard Huxton dev em archonet.com
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Executando Funções de Conjuntos (Aggregates) no Plpython
  8/Jun/2003

A palestra que estarei ministrando na OSCON será sobre Executar Funções de Conjunto no PostgreSQL em plpython. Este assunto foi tratado superficialmente na Edição #23. Na conferência, a palestra terá mais exemplos e cobrirá mais detalhes. Eu terei prazer em publicar os exemplos adicionais e o texto da palestra após a conferência. Uma curta descrição da palestra se encontra logo abaixo:

Um questionamento constante e aparente em muitos forums é como executar funções no registro corrente baseado no registro anterior. Esta palestra mostrará uma técnica em detalhe. Esta técnica pode ser aplicada em diversas tarefas distintas provendo uma nova maneira de utilizar seus dados.

Esta palestra demonstrará como usar as funções do pl/python no PostgreSQL para fazer executar cálculos inter-registros, como por exemplo, executar somatórios e a diferença de tempo entre um registro e o próximo. Conhecimento anterior sobre pl/python não é requerido.

Colaboradores: elein em varlena.com

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
Traduzidos por Juliano da Silva Ignacio

Google
Search General Bits & varlena.com Search WWW