Comunidade, atualmente faço a seguinte operação via o SQL abaixo (executado 
dinamicamente):

 

sql_aux = 'INSERT INTO "DTF_TENSAO_BARRAS" 
(id_barra,"data_hora",valor,id_tipo_dia) 

                        SELECT DISTINCT A.ID, B.BH_DTHR, B.VALOR,' || 
cast(idtipodia as varchar) || ' FROM PAS_R A, BHPAS_H_' || 

                        replace(CAST(data AS character varying(300)), '-','_') 
|| ' B WHERE A.BH_CHAVE=B.BH_CHAVE 

                        AND B.BH_DTHR > ''' || CAST(data AS character 
varying(300)) || ' ' || hora_maxima_do_dia || ''' AND B.BH_DTHR < ''' || 

                        CAST(data AS character varying(300)) || ' 23:59:59'' 

                        AND B.BH_CHAVE IN (SELECT BH_CHAVE FROM PAS_R WHERE ID 
= ''' || record_ids_barras.id_barra || ''' );';

 

EXECUTE sql_aux;

 

A questão é que a tabela BHPAS_YYYY_MM_DD apresenta às vezes mais de 06 milhões 
de registros 

(com a cláusula DISTINCT; sem essa cláusula o numero de registros triplica (3x) 
devido ao um erro estranho na aplicação 

que alimenta o banco; a tabela BHPAS_YYYY_MM_DD não possui chave primária - não 
fui eu quem criou o banco e nem posso alterar) 

e esses mesmos 06 milhões ainda serão passados pelo WHERE da consulta 
resultando em média + ou - 6000 registros pra 

serem copiados para tabela "DTF_TENSAO_BARRAS", a qual não está vazia.

 

Da maneira que estou fazendo hoje, a consulta está demorando quase 10 segundos 
(para as tabelas que têm + 06 milhões)

 e isso apenas pra um dia. Quando roda a consulta mensal, isso pode levar até 
mais de 5 minutos, 

uma vez que como a consulta é dinâmica e o plano de execução não é reutilizado. 
(SOCORRO!!!!!!!!!!! ahauahauahuhuahu).

 

PERGUNTA: Tem como otimizar essa consulta de alguma maneira? Dá pra usar o COPY 
nesse caso?

 

PostgreSQL 8.2.4  - S.O. CentOS 4.5

 

Eis as tabelas (e índices) envolvidos nessa consulta:

 

CREATE TABLE bhpas_h_2009_01_29

(

  bh_dthr timestamp with time zone,

  bh_chave integer,

  bh_variacao integer,

  flag integer,

  flagest smallint,

  linfa real,

  linfe real,

  linfu real,

  lsupa real,

  lsupe real,

  lsupu real,

  resnorm real,

  rgalr smallint,

  valest real,

  valor real

)

WITH (OIDS=FALSE)

TABLESPACE sagebhtab;

ALTER TABLE bhpas_h_2009_01_29 OWNER TO sage;

 

CREATE INDEX pas_h_2009_01_29_a_i

  ON bhpas_h_2009_01_29

  USING btree

  (bh_chave, bh_dthr)

TABLESPACE sagebhind;

 

CREATE TABLE pas_r

(

  bh_dthr_ini timestamp with time zone,

  bh_dthr_fim timestamp with time zone,

  bh_sinonimo integer,

  bh_chave integer,

  bh_indtr integer,

  eqp character(18),

  estacao character(12),

  histper smallint,

  id character(24),

  nome character(42),

  tac character(12),

  tipoe smallint,

  tpeqp smallint

)

WITH (OIDS=FALSE)

TABLESPACE sagebhref;

ALTER TABLE pas_r OWNER TO sage;

 

 

CREATE UNIQUE INDEX pas_r_a_i

  ON pas_r

  USING btree

  (bh_chave, bh_dthr_ini, bh_dthr_fim)

TABLESPACE sagebhind;

 

 

CREATE INDEX pas_r_b_i

  ON pas_r

  USING btree

  (id)

TABLESPACE sagebhind;

 

 

 

CREATE TABLE "DTF_TENSAO_BARRAS"

(

  id_barra character varying(20) NOT NULL,

  data_hora timestamp without time zone NOT NULL,

  valor real,

  status_carga_1 character varying(10), -- Pode receber 02 valores:...

  status_carga_2 character varying(10), -- Pode receber 04 valores:...

  id_tipo_dia integer,

  id_tipo_carga integer,

  CONSTRAINT "pk-dtf-tensao-barras" PRIMARY KEY (id_barra, data_hora),

  CONSTRAINT "fk-dtf-tensao-barras" FOREIGN KEY (id_barra)

      REFERENCES "DTF_IDS_BARRAS" (id_barra) MATCH SIMPLE

      ON UPDATE NO ACTION ON DELETE NO ACTION

)

 

CREATE INDEX "indice1-dtf-tensao-barras"

  ON "DTF_TENSAO_BARRAS"

  USING btree

  (id_barra, data_hora);

 

_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a