Sugestão de estrutura de carga: As cargas de tabelas dimensão funcionam um pouco diferente das tabelas fato, onde, algumas fato possuem dependência das dimensões, portanto os fatos não devem ser atualizados antes das dimensões. Outro ponto é que os fatos podem ser executados em paralelo agrupados por empresa sem problemas de conflito de dados. Uma estrutura performática ficaria da seguinte forma Um job inicial que fará a atualização das dimensões Bloco de código |
---|
title | JOB DIMENSÃO |
---|
collapse | true |
---|
| Begin
Pkg_Etl_Gerencial.sp_Executacargageral( '', sysdate, sysdate, 'D');
End;
|
Jobs agrupados por empresa que vão executar em paralelo e serão disparados pelo job de dimensão quando o mesmo terminar. Bloco de código |
---|
title | JOB FATO |
---|
collapse | true |
---|
| -- Supondo que exista o NROEMPRESA 1 até o 30 cadastrados, a carga pode ser dividida em 3 jobs com 10 empresas cada, ficando da forma:
-- JOB 1
Begin
Pkg_Etl_Gerencial.sp_Executacargageral( '1,2,3,4,5,6,7,8,9,10', sysdate, sysdate, 'F' );
End;
-- JOB 2
Begin
Pkg_Etl_Gerencial.sp_Executacargageral( '11,12,13,14,15,16,17,18,19,20', sysdate, sysdate, 'F' );
End;
-- JOB 3
Begin
Pkg_Etl_Gerencial.sp_Executacargageral( '21,22,23,24,25,26,27,28,29,30', sysdate, sysdate, 'F' );
End; |
Foi criada uma rotina de divisão da carga que atende os ambientes configurados com paralelismo para execução de jobs. Esta rotina consiste em criar uma tabela de agrupamento onde será feita a distribuição das empresas de acordo com o volume de vendas do ano de 2023 e depois, a partir deste agrupamento, são disparados 5 cargas em paralelo a partir da chamada de um job principal. Para criar a estrutura é necessário seguir os passos: Criação da tabela de agrupamentos Bloco de código |
---|
title | Tabela de agrupamento de cargas |
---|
collapse | true |
---|
| CREATE TABLE ETL_AGRUPAMENTOCARGA( AGRUPAMENTO INTEGER, NROEMPRESA NUMBER(6) ); |
Execução do script de agrupamento das empresas Bloco de código |
---|
title | Agrupamento de empresas por volume de vendas |
---|
collapse | true |
---|
| declare
qtdQuebra integer := 4;
vnJob integer := 1;
begin
for vtEmp1 in ( select a.nroempresa, sum(a.qtdvda)
from mrl_custodia a
where a.dtaentradasaida between '01-JAN-2023' and '31-DEC-2023'
group by a.nroempresa
order by sum(a.qtdvda) desc )
loop
insert into etl_agrupamentocarga( agrupamento, nroempresa ) values ( vnjob, vtEmp1.Nroempresa );
vnJob := vnJob + 1;
commit;
if vnJob > qtdQuebra then
vnJob := 1;
end if;
end loop;
vnJob := 1;
for vtEmp2 in ( select e.nroempresa
from max_empresa e
where not exists ( select 1
from etl_agrupamentocarga c
where e.nroempresa = c.nroempresa ) )
loop
insert into etl_agrupamentocarga( agrupamento, nroempresa ) values ( vnjob, vtEmp2.Nroempresa );
vnJob := vnJob + 1;
commit;
if vnJob > qtdQuebra then
vnJob := 1;
end if;
end loop;
end;
/ |
Criação dos jobs da carga Bloco de código |
---|
title | Criação dos jobs paralelos |
---|
collapse | true |
---|
| -- CRIA O JOB DE CARGA DO PRIMEIRO AGRUPAMENTO
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_FATO_1',
job_type => 'PLSQL_BLOCK',
job_action => 'declare
vsNroEmpresa varchar2(4000);
begin
select listagg(a.nroempresa, '','') within group (order by a.nroempresa)
into vsNroEmpresa
from etl_agrupamentocarga a
where a.agrupamento = 1;
pkg_etl_gerencial.sp_dimprodutoempresa( vsNroEmpresa );
pkg_etl_gerencial.sp_dimprodutoempresasegmento( vsNroEmpresa );
pkg_etl_gerencial.sp_ExecutaCargaGeral( vsNroEmpresa,
trunc(Sysdate),
trunc(Sysdate),
''F'');
end;',
start_date => to_date(null),
auto_drop => false,
comments => 'Grupo 1 carga DW - disparado pelo DW_CARGA_DIM_1'
);
END;
/
-- CRIA O JOB DE CARGA DO SEGUNDO AGRUPAMENTO
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_FATO_2',
job_type => 'PLSQL_BLOCK',
job_action => 'declare
vsNroEmpresa varchar2(4000);
begin
select listagg(a.nroempresa, '','') within group (order by a.nroempresa)
into vsNroEmpresa
from etl_agrupamentocarga a
where a.agrupamento = 2;
pkg_etl_gerencial.sp_dimprodutoempresa( vsNroEmpresa );
pkg_etl_gerencial.sp_dimprodutoempresasegmento( vsNroEmpresa );
pkg_etl_gerencial.sp_ExecutaCargaGeral( vsNroEmpresa,
trunc(Sysdate),
trunc(Sysdate),
''F'');
end;',
start_date => to_date(null),
auto_drop => false,
comments => 'Grupo 2 carga DW - disparado pelo DW_CARGA_DIM_1'
);
END;
/
-- CRIA O JOB DE CARGA DO TERCEIRO AGRUPAMENTO
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_FATO_3',
job_type => 'PLSQL_BLOCK',
job_action => 'declare
vsNroEmpresa varchar2(4000);
begin
select listagg(a.nroempresa, '','') within group (order by a.nroempresa)
into vsNroEmpresa
from etl_agrupamentocarga a
where a.agrupamento = 3;
pkg_etl_gerencial.sp_dimprodutoempresa( vsNroEmpresa );
pkg_etl_gerencial.sp_dimprodutoempresasegmento( vsNroEmpresa );
pkg_etl_gerencial.sp_ExecutaCargaGeral( vsNroEmpresa,
trunc(Sysdate),
trunc(Sysdate),
''F'');
end;',
start_date => to_date(null),
auto_drop => false,
comments => 'Grupo 3 carga DW - disparado pelo DW_CARGA_DIM_1'
);
END;
/
-- CRIA O JOB DE CARGA DO QUARTO AGRUPAMENTO
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_FATO_4',
job_type => 'PLSQL_BLOCK',
job_action => 'declare
vsNroEmpresa varchar2(4000);
begin
select listagg(a.nroempresa, '','') within group (order by a.nroempresa)
into vsNroEmpresa
from etl_agrupamentocarga a
where a.agrupamento = 4;
pkg_etl_gerencial.sp_dimprodutoempresa( vsNroEmpresa );
pkg_etl_gerencial.sp_dimprodutoempresasegmento( vsNroEmpresa );
pkg_etl_gerencial.sp_ExecutaCargaGeral( vsNroEmpresa,
trunc(Sysdate),
trunc(Sysdate),
''F'');
end;',
start_date => to_date(null),
auto_drop => false,
comments => 'Grupo 4 carga DW - disparado pelo DW_CARGA_DIM_1'
);
END;
/
-- CRIA O JOB DE CARGA DO QUINTO AGRUPAMENTO - NOVAS EMPRESAS
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_FATO_5',
job_type => 'PLSQL_BLOCK',
job_action => 'declare
vsNroEmpresa varchar2(1000);
begin
select listagg(a.nroempresa, '','') within group (order by a.nroempresa)
into vsNroEmpresa
from max_empresa a
where not exists( select 1
from etl_agrupamentocarga b
where b.nroempresa = a.nroempresa );
if vsNroEmpresa is not null then
pkg_etl_gerencial.sp_dimprodutoempresa( vsNroEmpresa );
pkg_etl_gerencial.sp_dimprodutoempresasegmento( vsNroEmpresa );
pkg_etl_gerencial.sp_ExecutaCargaGeral( vsNroEmpresa,
trunc(Sysdate),
trunc(Sysdate),
''F'');
end if;
end;',
start_date => to_date(null),
auto_drop => false,
comments => 'Carga de novas empresas - disparado pelo DW_CARGA_DIM_1'
);
END;
/ |
Criação do job principal que vai executar todo dia e vai disparar as demais rotina Bloco de código |
---|
title | Criação do job principal |
---|
collapse | true |
---|
| -- CRIA O JOB DE CARGA PRINCIPAL, QUE VAI INSERIR AS DIMENSÕES QUE SAO DEPENDENCIA DE FATOS E DISPARAR OS OUTROS JOBS
-- NO EXEMPLO ELE ESTA CONFIGURADO PARA EXECUTAR TODO DIA AS 00:05H
-- PARA ALTERAR A HORA DE EXECUÇAO É NECESSARIO ALTERAR O PARAMETRO repeat_interval => 'Freq=Daily;ByHour=00;ByMinute=05;BySecond=00'
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'DW_CARGA_DIM_1',
job_type => 'PLSQL_BLOCK',
job_action => 'begin
pkg_etl_gerencial.sp_DimCidade;
pkg_etl_gerencial.sp_DimEmpresa;
pkg_etl_gerencial.sp_DimCheckout;
pkg_etl_gerencial.sp_DimCliente;
pkg_etl_gerencial.sp_DimClienteEnd;
pkg_etl_gerencial.sp_DimProduto;
pkg_etl_gerencial.sp_DimProdutoembalagem;
pkg_etl_gerencial.sp_DimProdutoCodigo;
pkg_etl_gerencial.sp_DimProdutoPrincipioAtivo;
pkg_etl_gerencial.sp_DimFornecedor;
pkg_etl_gerencial.sp_DimComprador;
pkg_etl_gerencial.sp_DimRepresentante;
pkg_etl_gerencial.sp_DimArvoreCategoria;
pkg_etl_gerencial.sp_DimArvoreCategoriaFam;
pkg_etl_gerencial.sp_DimCategoria;
pkg_etl_gerencial.sp_DimConcorrente;
pkg_etl_gerencial.sp_DimSegmento;
pkg_etl_gerencial.sp_DimCodgeraloper;
pkg_etl_gerencial.sp_DimLocal;
pkg_etl_gerencial.sp_DimFormaPagto;
pkg_etl_gerencial.sp_DimCondicaoPagto;
pkg_etl_gerencial.sp_DimTabVenda;
pkg_etl_gerencial.sp_DimTributacao;
pkg_etl_gerencial.sp_DimClienteSeg;
pkg_etl_gerencial.sp_DimReceitaRendto;
pkg_etl_gerencial.sp_DimLista;
pkg_etl_gerencial.sp_DimListaItem;
pkg_etl_gerencial.sp_DimClassifComercial;
pkg_etl_gerencial.sp_DimClienteEndSetor;
pkg_etl_gerencial.sp_DimProdSimilar;
pkg_etl_gerencial.sp_DimUsuario;
pkg_etl_gerencial.sp_DimZonaVenda;
pkg_etl_gerencial.sp_DimOcorrenciaDevolucao;
pkg_etl_gerencial.sp_DimClientePromotor;
pkg_etl_gerencial.sp_DimClienteGrupo;
pkg_etl_gerencial.sp_DimSazonalidade;
dbms_scheduler.run_job(''DW_CARGA_FATO_1'', false);
dbms_scheduler.run_job(''DW_CARGA_FATO_2'', false);
dbms_scheduler.run_job(''DW_CARGA_FATO_3'', false);
dbms_scheduler.run_job(''DW_CARGA_FATO_4'', false);
dbms_scheduler.run_job(''DW_CARGA_FATO_5'', false);
end;',
start_date => to_date(null),
repeat_interval => 'Freq=Daily;ByHour=00;ByMinute=05;BySecond=00',
auto_drop => false,
comments => 'Carga dimensoes que nao sao associadas a empresa e que sao dependencia dos fatos'
);
END;
/ |
Abaixo são apresentados alguns vídeos práticos sobre as configurações de carga:
Conector de Widget |
---|
url | https://www.youtube.com/watch?v=PIzoRZmmjco |
---|
|
Vídeo 3 - Configuração dos Fatos Conector de Widget |
---|
url | https://www.youtube.com/watch?v=JJaAQL8JkTw |
---|
|
Vídeo 4 - Sugestão 1 de rotina de carga Conector de Widget |
---|
url | https://www.youtube.com/watch?v=JJaAQL8JkTw |
---|
|
Vídeo 4 - Sugestão 1 de rotina de carga - Continuação Conector de Widget |
---|
url | https://www.youtube.com/watch?v=PtF6Yt3CA4Y |
---|
|
Vídeo 5 - Sugestão 2 de rotina de carga |