Execução de função extremamente lenta - Não finaliza
Teste
Sandra Guedelha
Curtidas 0
Respostas
Sandra Guedelha
16/09/2013
Caros,
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' ;
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
Jair N.
16/09/2013
Bom dia, olha só é o seguinte, sua função aparentemente não tem nada que prova essa lentidão de processo, como ela não tem retorno "void" então fica difícil saber quantos registros podem ser incluídos em período de tempo, você poderia debugar a operação utilizando algumas ferramentas não tenho nenhuma para linux... resta também saber se a configuração do "pg_hba.conf" no linxux como deve estar. travamento de registros etc. Como é um processo em lote seria bom utilizar os comandos para validação como "INFO, NOTICE, WARNING, ERROR," na inserção eu prefiro urilizar o comando "EXECUTE" para processar fora do lote, bem, é só um palpite ok...
Atc.
Atc.
Caros,
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' ;
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
Ronaldo Lanhellas
16/09/2013
Ressuscitando este tópico, é importante salientar algo que não foi esclarecido:
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.
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