Boa tarde a todos,
Possuo um sistema web onde o controle de usuários acontece através de
tabelas de usuários e controle de permissões na aplicação. Para realizar
o registro de mudanças nas tabelas por gatilhos, crio uma tabela
temporária com o id do usuário e na hora de registrar as mudanças via
trigger capturo desta tabela temporária o id do usuário armazenando os
dados alterados com o usuário que realizou a operação na aplicação.
Acontece que, algumas operações de backend rodam abaixo da aplicação,
através de triggers e/ou chamadas internas via webservice. Para estas
operações, a tabela temporária não vai existir e não posso inserir
nenhum valor de uusário nela, mas nestes casos eu consigo realizar o
controle através de usuários do próprio banco (cada aplicação de backend
roda com um usuário específico do postgres).
Na minha função, inicio a chamada para recolher o valor do usuário da
seguinte forma:
...
-- Cria o diretório temporário para ocaso da execução ser feita através
das chamadas de backend
CREATE TEMP TABLE IF NOT EXISTS tmp_usuario_logado (id_usuario_cliente
VARCHAR(30));
-- Recupera o id do usuário, caso não exista (tabela recem criada),
recupera o current_user do banco
SELECT id_usuario_cliente
INTO USUARIO_CLIENTE
FROM (SELECT id_usuario_cliente::text AS id_usuario_cliente,
0 AS prioridade
FROM tmp_usuario_logado
UNION
SELECT current_user AS id_usuario_cliente,
1 AS prioridade
ORDER BY prioridade ASC
LIMIT 1) AS dados_usuario;
...
A operação em sim funciona e atende minha necessidade de auditoria (por
usuário do banco ou por id do usuário do cliente). Sendo que, como
realizamos muitas transações de insert, update,delete em lote, o tempo
de criação desta tabela e o select no mesmo acaba ganhando proporções
que podem impactar no desempenho do sistema no futuro.
* Existe alguma forma de se criar uma variável dinâmica no Postgres
setada na aplicação (por exemplo via SET) para que eu elimine a criação
e consulta nesta tabela temporária?
* No caso de não existir na atual versão do postgres (acabo de migrar
para a 9.3.2), existe alguma forma de reduzir a operação deste select
que estou usando?
O Explain das operações (acontecem em cada operação de INSERT, DELETE,
UPDATE *por linha*).
CREATE TEMP TABLE IF NOT EXISTS tmp_usuario_logado (id_usuario_cliente
VARCHAR(30));
CREATE TABLE
Time: 6,246 ms
---------------------------
EXPLAIN ANALYZE SELECT id_usuario_cliente
INTO USUARIO_CLIENTE
FROM (SELECT id_usuario_cliente::text AS id_usuario_cliente,
0 AS prioridade
FROM tmp_usuario_logado
UNION
SELECT current_user AS id_usuario_cliente,
1 AS prioridade
ORDER BY prioridade ASC
LIMIT 1) AS dados_usuario;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------
Subquery Scan on foo (cost=118.04..118.06 rows=1 width=32) (actual
time=0.028..0.029 rows=1 loops=1)
-> Limit (cost=118.04..118.05 rows=1 width=4) (actual
time=0.028..0.028 rows=1 loops=1)
-> Sort (cost=118.04..124.05 rows=2401 width=4) (actual
time=0.027..0.027 rows=1 loops=1)
Sort Key: (0)
Sort Method: quicksort Memory: 25kB
-> HashAggregate (cost=82.03..106.04 rows=2401
width=4) (actual time=0.017..0.020 rows=2 loops=1)
-> Append (cost=0.00..70.02 rows=2401 width=4)
(actual time=0.006..0.011 rows=2 loops=1)
-> Seq Scan on tmp_usuario_logado
(cost=0.00..46.00 rows=2400 width=4) (actual time=0.006..0.007 rows=1
loops=1)
-> Subquery Scan on "*SELECT* 2"
(cost=0.00..0.02 rows=1 width=0) (actual time=0.003..0.003 rows=1 loops=1)
-> Result (cost=0.00..0.01 rows=1
width=0) (actual time=0.002..0.002 rows=1 loops=1)
Total runtime: 0.067 ms
Atenciosamente,
--
+--------------------------------------------------------------------------+
| Daniel Cordeiro de Morais Neto
| Diretor de TI - Portal de Cotações e-Compras
| Sócio-diretor ADM Soluções em Informática LTDA
| daniel.cordeiro(at)cotacoesecompras.com.br
| dmoraisn(at)gmail.com
| www.cotacoesecompras.com.br
| Fone: (083)8724-4440
| Gentoo User
| http://twitter.com/dmoraisn
+--------------------------------------------------------------------------+
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral