Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Rodrigo Ricardo

SQL Lenta

Recommended Posts

Olá amigos, há algum tempo desenvolvi um relatório onde mostra um balancete das contas a pagar do meu cliente, o problema é que a cada dia que se passa tem aumentado mais o tempo do processamento da sql desse relatório, montei uma stored procedure e a chamo ao executar a sql, porem o relatório está demorando cerca de 4 horas para executar. Estou usando o firebird 2.1 e meu computador é um Dual Core com 4gb de ram. Quando é executado no servidor da empresa q é um Xeon demora certa de umas 3 horas.

Essa já é a segunda reestruturação que faço nesse relatório, antes não usava o stored procedure, fazia direto na sql, mas para ganhar performace fiz com stored procedure, porém agora já está novamente lento.

 

abaixo vou enviar o modelo da sql e stored procedure que estou executando, caso alguém tenha alguma dica de como turbinar isso me avise por favor.

a tabela de apagar tem cerca de 40 mil registros

a tabela de ligapgto tem cerca de 38 mil registros

a tabela de pagamento tem cerca de 21 mil registros

a tabela de fornecedor tem cerca de 3 mil registros.

 

 

##########SQL

SELECT AVCTO, ADATA, ACODFOR, FORRAZAO, ANUMDOC, AOBS, ASTATUS, ACODUNI, AVALOR

FROM SP_BALANCETE_APAGAR(:PDATA,:PUNIDADE)

WHERE AVALOR > 0

ORDER BY FORRAZAO, ACODFOR, AVCTO

 

##########STORED PROCEDURE

CREATE OR ALTER PROCEDURE SP_BALANCETE_APAGAR (

pdata date,

punidade integer)

returns (

avcto date,

adata date,

acodfor integer,

forrazao varchar(40),

anumdoc varchar(15),

aobs varchar(80),

astatus varchar(7),

acoduni integer,

avalor numeric(9,2))

as

BEGIN

FOR

 

SELECT A.AVCTO, A.ADATALCTO, A.ACODFOR, F.FORRAZAO, A.ANUMDOC, A.AOBS, A.ASTATUS, A.ACODUNI,

SUM(A.AVALOR - COALESCE((SELECT SUM(L.LVALPGTO)

FROM LIGAPGTO L LEFT OUTER JOIN PAGAMENTO P ON (L.LSEQPGTO = P.PSEQUENCIA)

WHERE (P.SISUNIDADE = :PUNIDADE) AND ( A.ASEQUENCIA = L.LSEQCONTA ) AND ( P.PDATA <= :PDATA )), 0)) AS AVALOR

FROM APAGAR A LEFT OUTER JOIN FORNECEDOR F ON ( A.ACODFOR = F.FORCODIGO )

WHERE ( A.ADATALCTO <= :PDATA ) AND A.ACODUNI = :PUNIDADE

GROUP BY A.AVCTO, A.ADATALCTO, A.ACODFOR, F.FORRAZAO, A.ANUMDOC, A.AOBS, A.ASTATUS, A.ACODUNI

 

INTO :AVCTO, :ADATA, :ACODFOR, :FORRAZAO, :ANUMDOC, :AOBS, :ASTATUS, :ACODUNI, :AVALOR

 

DO SUSPEND;

END

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá Ricardo!

 

Bem, seu comando está muito lento por alguns motivos, mas como não conheco o relacionamento e do seu banco nao tenho afirmar com certeza que há como melhorar.

 

O "LEFT" é sempre muito lento, sempre que possivel use o INNER.

Uma "SELECT" dentro de outra, como é o caso, também deixa lento seu comando.

 

Se você conseguir resolver essas duas coisas você ja vai ganhar muito desempenho. Se voce quiser, posta aqui o modelo relacional do seu banco, que fica mais facil te ajudar!

Compartilhar este post


Link para o post
Compartilhar em outros sites

As tabelas tem índices ?

 

Não as tabelas não tem indice, apenas chaves primarias e estrangerias

 

como faço para trabalhar com indices?

 

Olá Ricardo!

 

Bem, seu comando está muito lento por alguns motivos, mas como não conheco o relacionamento e do seu banco nao tenho afirmar com certeza que há como melhorar.

 

O "LEFT" é sempre muito lento, sempre que possivel use o INNER.

Uma "SELECT" dentro de outra, como é o caso, também deixa lento seu comando.

 

Se você conseguir resolver essas duas coisas você ja vai ganhar muito desempenho. Se voce quiser, posta aqui o modelo relacional do seu banco, que fica mais facil te ajudar!

 

 

Troquei os LEFT por INNER, não havia me atentado para essa questão, quanto a deixar uma sql dentro da outra realmente precido disso.

 

vou enviar os script de criação do banco da forma que foram criados no banco:

 

CREATE TABLE FORNECEDOR (

FORCODIGO INTEGER NOT NULL,

FORRAZAO VARCHAR(40),

FORFANTASIA VARCHAR(40),

FORCNPJ VARCHAR(18),

FORIERG VARCHAR(18),

FORENDERECO VARCHAR(50),

FORBAIRRO VARCHAR(25),

FORCIDADE VARCHAR(30),

FORCEP CHAR(9),

FORUF CHAR(2),

FORFONE CHAR(13),

FORFAX CHAR(13),

FORCELULAR CHAR(13),

FOREMAIL VARCHAR(60),

FORCONTATO VARCHAR(30),

FOROBS BLOB SUB_TYPE 1 SEGMENT SIZE 255,

FORTIPO VARCHAR(10) NOT NULL,

FORNUMERO VARCHAR(6),

FORCODIGOIBGE INTEGER,

FORPAIS INTEGER NOT NULL,

SISUNIDADE INTEGER NOT NULL,

FORCODIGOCONTABIL VARCHAR(20),

FORFORMAPAGAMENTO VARCHAR(12) NOT NULL,

FORCODSUFRAMA VARCHAR(15),

FORPRESTSERVICO CHAR(1)

);

 

ALTER TABLE FORNECEDOR ADD PRIMARY KEY (FORCODIGO);

 

/******************************************************************************/

 

CREATE TABLE APAGAR (

ASEQUENCIA INTEGER NOT NULL,

ADATA DATE,

AVCTO DATE,

ANUMDOC VARCHAR(10),

ATIPO VARCHAR(10),

ACODFOR INTEGER NOT NULL,

AVALOR NUMERIC(9,2),

ACODUNI INTEGER NOT NULL,

ACODCON INTEGER NOT NULL,

ACODSUB INTEGER NOT NULL,

AOBS VARCHAR(80),

APARCIAL NUMERIC(9,2),

ASTATUS VARCHAR(7),

AORIGEM VARCHAR(10),

ANUMCOMPRA INTEGER,

CODMODELO INTEGER NOT NULL,

ACODCENTROCUSTO INTEGER NOT NULL,

ATIPOSUB CHAR(1) NOT NULL,

ADATALCTO DATE,

SISINCLUSAO_USUARIO INTEGER,

SISINCLUSAO_DATA DATE,

SISINCLUSAO_HORA TIME,

SISEDICAO_USUARIO INTEGER,

SISEDICAO_DATA DATE,

SISEDICAO_HORA TIME,

RPA_VRFRETE NUMERIC(9,2) DEFAULT 0,

RPA_VRADIANTAMENTO NUMERIC(9,2) DEFAULT 0,

RPA_VRIRRF NUMERIC(9,2) DEFAULT 0,

RPA_VRINSS NUMERIC(9,2) DEFAULT 0,

RPA_VRICMS_RPA NUMERIC(9,2) DEFAULT 0,

RPA_VRINSS_RPA NUMERIC(9,2) DEFAULT 0,

RPA_NOTAS VARCHAR(80),

RPA_ICMSCOCODIGO INTEGER,

RPA_ICMSSCODIGO INTEGER,

RPA_ICMSTIPO CHAR(1),

RPA_ICMSCOCODIGO2 INTEGER,

RPA_ICMSSCODIGO2 INTEGER,

RPA_ICMSTIPO2 CHAR(1),

RPA_INSSCOCODIGO INTEGER,

RPA_INSSSCODIGO INTEGER,

RPA_INSSTIPO CHAR(1),

RPA_INSSCOCODIGO2 INTEGER,

RPA_INSSSCODIGO2 INTEGER,

RPA_INSSTIPO2 CHAR(1)

);

 

ALTER TABLE APAGAR ADD PRIMARY KEY (ASEQUENCIA);

/******************************************************************************/

 

CREATE TABLE LIGAPGTO (

LSEQPGTO INTEGER NOT NULL,

LSEQCONTA INTEGER NOT NULL,

LVALPGTO NUMERIC(9,2),

LVALDESC NUMERIC(9,2),

LVALJURO NUMERIC(9,2)

);

 

ALTER TABLE LIGAPGTO ADD CONSTRAINT FK_LIGAPGTO PRIMARY KEY (LSEQPGTO, LSEQCONTA);

 

/******************************************************************************/

 

CREATE TABLE PAGAMENTO (

PSEQUENCIA INTEGER NOT NULL,

PDATA DATE,

PCODFOR INTEGER NOT NULL,

PVALOR NUMERIC(9,2) NOT NULL,

PTIPOPGTO VARCHAR(8),

POBS VARCHAR(80),

PDESCONTO NUMERIC(9,2),

PJUROS NUMERIC(9,2),

PAPAGAR NUMERIC(9,2),

SISUNIDADE INTEGER NOT NULL,

EXPORTADO CHAR(1),

EXPORTADO_DATA DATE,

EXPORTADO_USUARIO VARCHAR(15),

SISINCLUSAO_USUARIO INTEGER,

SISINCLUSAO_DATA DATE,

SISINCLUSAO_HORA TIME,

PTIPODESCONTO CHAR(1) DEFAULT 'N'

);

 

ALTER TABLE PAGAMENTO ADD PRIMARY KEY (PSEQUENCIA);

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ricardo, crie as FK, com isso a base tera os indices e será mais rapida!

 

exemplo e FK:

 

alter table APAGAR add constraint FK_APAGAR_FORNECEDOR foreign key (ACODFOR) references FORNECEDOR(FORCODIGO).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ricardo, crie as FK, com isso a base tera os indices e será mais rapida!

 

exemplo e FK:

 

alter table APAGAR add constraint FK_APAGAR_FORNECEDOR foreign key (ACODFOR) references FORNECEDOR(FORCODIGO).

 

já tem as FK criadas... mas tb nao resolveu...

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.