Fórum Execução de função extremamente lenta - Não finaliza #455395
16/09/2013
0
Sandra Guedelha
Curtir tópico
+ 0Posts
16/09/2013
Sandra Guedelha
Temos o Postgresql 9.1 intalado em um servidor Linux Red hat.
Na sexta-feira passada iniciamos a execução de uma função que envolvia duas tabelas : uma com 14985 registros e a outra com 920487 registros.
O script continua executando até agora, não finaliza.
Analisando a função do analista, resolvemos restaurar o banco no servidor de homologação e alterar a função cast, dentro da função.
O script passou a executar em 5 minutos.
Outra observação: o analista solicitou o backup do banco e executou no desktop dele a função sem nenhuma alteração e executou em 4 horas. O desktop dele é um windows 7.
A configuração do desktop dele é a padrão da instalação.
Função original:
CREATE OR REPLACE FUNCTION preencherTabelaVinculoNcm() RETURNS void AS
$BODY$
DECLARE
r mineracao.ncm%rowtype ;
idVinculo text;
BEGIN
FOR r IN SELECT *from mineracao.ncm
WHERE ids_produto_vinculo is not null and ids_produto_vinculo <> 'null'
LOOP
for idVinculo in select regexp_split_to_table(r.ids_produto_vinculo, ';')
loop
IF idVinculo<> 'null' THEN
IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE CAST(pv.id AS TEXT) = idVinculo) THEN
INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (CAST(idVinculo AS BIGINT), r.id);
END IF;
END IF;
end loop;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
Script alterado (executou em 5 minutos):
CREATE OR REPLACE FUNCTION preencherTabelaVinculoNcm() RETURNS void AS
$BODY$
DECLARE
r mineracao.ncm%rowtype ;
idVinculo text;
idVinculoInt bigint; -- variavel criada para suportar o CAST
BEGIN
FOR r IN SELECT *from mineracao.ncm WHERE ids_produto_vinculo is not null and ids_produto_vinculo <> 'null'
LOOP
for idVinculo in select regexp_split_to_table(r.ids_produto_vinculo, ';')
loop
IF idVinculo<> 'null' THEN
idVinculoInt:=cast(idVinculo as bigint); -- CAST
IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE pv.id = idVinculoInt) THEN
-- IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE CAST(pv.id AS TEXT) = idVinculo) THEN
INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (idVinculoInt, r.id);
--INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (CAST(idVinculo AS BIGINT), r.id);
END IF;
END IF;
end loop;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
Gostei + 0
17/09/2013
Jair N.
Atc.
Temos o Postgresql 9.1 intalado em um servidor Linux Red hat.
Na sexta-feira passada iniciamos a execução de uma função que envolvia duas tabelas : uma com 14985 registros e a outra com 920487 registros.
O script continua executando até agora, não finaliza.
Analisando a função do analista, resolvemos restaurar o banco no servidor de homologação e alterar a função cast, dentro da função.
O script passou a executar em 5 minutos.
Outra observação: o analista solicitou o backup do banco e executou no desktop dele a função sem nenhuma alteração e executou em 4 horas. O desktop dele é um windows 7.
A configuração do desktop dele é a padrão da instalação.
Função original:
CREATE OR REPLACE FUNCTION preencherTabelaVinculoNcm() RETURNS void AS
$BODY$
DECLARE
r mineracao.ncm%rowtype ;
idVinculo text;
BEGIN
FOR r IN SELECT *from mineracao.ncm
WHERE ids_produto_vinculo is not null and ids_produto_vinculo <> 'null'
LOOP
for idVinculo in select regexp_split_to_table(r.ids_produto_vinculo, ';')
loop
IF idVinculo<> 'null' THEN
IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE CAST(pv.id AS TEXT) = idVinculo) THEN
INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (CAST(idVinculo AS BIGINT), r.id);
END IF;
END IF;
end loop;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
Script alterado (executou em 5 minutos):
CREATE OR REPLACE FUNCTION preencherTabelaVinculoNcm() RETURNS void AS
$BODY$
DECLARE
r mineracao.ncm%rowtype ;
idVinculo text;
idVinculoInt bigint; -- variavel criada para suportar o CAST
BEGIN
FOR r IN SELECT *from mineracao.ncm WHERE ids_produto_vinculo is not null and ids_produto_vinculo <> 'null'
LOOP
for idVinculo in select regexp_split_to_table(r.ids_produto_vinculo, ';')
loop
IF idVinculo<> 'null' THEN
idVinculoInt:=cast(idVinculo as bigint); -- CAST
IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE pv.id = idVinculoInt) THEN
-- IF EXISTS (SELECT pv.id FROM transito.produto_vinculo AS pv WHERE CAST(pv.id AS TEXT) = idVinculo) THEN
INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (idVinculoInt, r.id);
--INSERT INTO transito.vinculo_ncm (vinculo_id, ncm_id) VALUES (CAST(idVinculo AS BIGINT), r.id);
END IF;
END IF;
end loop;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
Gostei + 0
07/07/2014
Ronaldo Lanhellas
Não acho e tenho quase certeza que o CAST não é culpado de toda esta demora, muito improvável, foi apenas uma coincidência. Essa coincidência deve ter acontecido pelo seguinte: Ao executar a função pela primeira vez (antes de mudá-la), em algum ponto ela ficou "presa" devido a alguma outra transação que já estava utilizando uma tabela ou registro que você estava tentando ler (tem que checar o nível de isolação do seu PostgresSQL).
Depois você mudou a função e rodou novamente, mas a outra transação que estava bloqueando sua execução já tinha terminado e você conseguiu executar em 5 minutos, tendo a falsa impressão de que a alteração da função mudou algo. Mais uma vez ressalto, olhe o nível de isolação do seu SGBD, provavelmente ele foi um dos causadores deste problema.
Boa sorte.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)