SQL que demora 30 minutos!!!
Eu tenho este SQL:
select p.codigo,
p.descricao,
p.conta_corrente,
p.digito_conta,
p.tipo,
f.valor_pagto,
o.tipo as tipo_oper,
s.saldo_ini
from ficadptd p
left join fifluxoc f on f.cod_estab = p.cod_estab and
f.data_baixa >= :data_ini and
f.data_baixa <= :data_fim and
f.situacao = ´Baixado´ and
f.portador_pagto = p.codigo
left join fiopefin o on o.codigo = f.oper_financ
left join fiforpag r on r.codigo = f.forma_pagto and
r.flag_deb_cred = ´Sim´
left join fisalptd s on s.cod_estab = p.cod_estab and
s.portador = p.codigo and
s.ano_mes_ref = ´200211´
where p.cod_estab = :cod_estab
order by p.codigo
Ele usa este PLAN qdo. rodo:
Plan
PLAN SORT (JOIN (JOIN (JOIN (JOIN (P INDEX (RDB$PRIMARY134),F INDEX (RDB$PRIMARY143,FIFLUXOC_DT_BAIXA_SIT_IDX,FIFLUXOC_PORTADOR_PAGTO_IDX)),O INDEX (RDB$PRIMARY160)),R INDEX (RDB$PRIMARY144)),S INDEX (RDB$PRIMARY165)))
Adapted Plan
PLAN SORT (JOIN (JOIN (JOIN (JOIN (P INDEX (PK_FICADPTD),F INDEX (PK_FIFLUXOC,FIFLUXOC_DT_BAIXA_SIT_IDX,FIFLUXOC_PORTADOR_PAGTO_IDX)),O INDEX (PK_FIOPEFIN)),R INDEX (PK_FIFORPAG)),S INDEX (PK_FISALPTD)))
O problema: Eu já estou usando todos os índices possíveis mas ele continua muito lento!!! O problema não está no tempo de preparo (prepare) mas na execução e no fetch. O que eu posso fazer?
[b:26a17c14ab]OBS.:[/b:26a17c14ab]
Eu uso IB 6.01
Tamanho das tabelas:
FIFLUXOC -> uns 250000 registros
FICADPTD -> 266
FIFORPAG -> 3
FIOPEFIN -> 30
FISALPTD -> 14720
Os indices que as tabelas usadas possuem e que estao sendo usados no PLAN do select:
FIFLUXOC -> chave primaria (cod_estab,registro)
FIFLUXOC_DT_BAIXA_SIT_IDX (data_baixa,situacao)
FIFLUXOC_PORTADOR_PAGTO_IDX (portador_pagto)
FISALPTD -> chave promária (cod_estab,portador,ano_mes_ref)
FICADPTD -> chave primaria (cod_estab,codigo)
FIOPEFIN -> chave primaria (codigo)
FIFORPAG -> chave primaria (codigo)
Linhas retornadas pela consulta: Nao sei a quantia de linhas precisamente (mesmo pq. ele está lento a ponto de travar). Mas deve ser cerca de uns 2000 registros. É poka coisa.
Eu tenho um programinha que analiza o tempo de execucao de um SQL. Eu deixei rodando um tempao aqui e foi o unico lugar no qual eu consegui obter um resultado final.
Ele me trouxe os seguintes dados c/ respeito ao tempo:
Prepare time: 21 ms (ótimo!)
Execution time: 1795592 ms (olha o problema aqui!!! Isso dá cerca de meia hora!!!! Imagine!!!)
Fetch time: 759 ms
Por favor, alguém pode me ajudar?
Grata,
select p.codigo,
p.descricao,
p.conta_corrente,
p.digito_conta,
p.tipo,
f.valor_pagto,
o.tipo as tipo_oper,
s.saldo_ini
from ficadptd p
left join fifluxoc f on f.cod_estab = p.cod_estab and
f.data_baixa >= :data_ini and
f.data_baixa <= :data_fim and
f.situacao = ´Baixado´ and
f.portador_pagto = p.codigo
left join fiopefin o on o.codigo = f.oper_financ
left join fiforpag r on r.codigo = f.forma_pagto and
r.flag_deb_cred = ´Sim´
left join fisalptd s on s.cod_estab = p.cod_estab and
s.portador = p.codigo and
s.ano_mes_ref = ´200211´
where p.cod_estab = :cod_estab
order by p.codigo
Ele usa este PLAN qdo. rodo:
Plan
PLAN SORT (JOIN (JOIN (JOIN (JOIN (P INDEX (RDB$PRIMARY134),F INDEX (RDB$PRIMARY143,FIFLUXOC_DT_BAIXA_SIT_IDX,FIFLUXOC_PORTADOR_PAGTO_IDX)),O INDEX (RDB$PRIMARY160)),R INDEX (RDB$PRIMARY144)),S INDEX (RDB$PRIMARY165)))
Adapted Plan
PLAN SORT (JOIN (JOIN (JOIN (JOIN (P INDEX (PK_FICADPTD),F INDEX (PK_FIFLUXOC,FIFLUXOC_DT_BAIXA_SIT_IDX,FIFLUXOC_PORTADOR_PAGTO_IDX)),O INDEX (PK_FIOPEFIN)),R INDEX (PK_FIFORPAG)),S INDEX (PK_FISALPTD)))
O problema: Eu já estou usando todos os índices possíveis mas ele continua muito lento!!! O problema não está no tempo de preparo (prepare) mas na execução e no fetch. O que eu posso fazer?
[b:26a17c14ab]OBS.:[/b:26a17c14ab]
Eu uso IB 6.01
Tamanho das tabelas:
FIFLUXOC -> uns 250000 registros
FICADPTD -> 266
FIFORPAG -> 3
FIOPEFIN -> 30
FISALPTD -> 14720
Os indices que as tabelas usadas possuem e que estao sendo usados no PLAN do select:
FIFLUXOC -> chave primaria (cod_estab,registro)
FIFLUXOC_DT_BAIXA_SIT_IDX (data_baixa,situacao)
FIFLUXOC_PORTADOR_PAGTO_IDX (portador_pagto)
FISALPTD -> chave promária (cod_estab,portador,ano_mes_ref)
FICADPTD -> chave primaria (cod_estab,codigo)
FIOPEFIN -> chave primaria (codigo)
FIFORPAG -> chave primaria (codigo)
Linhas retornadas pela consulta: Nao sei a quantia de linhas precisamente (mesmo pq. ele está lento a ponto de travar). Mas deve ser cerca de uns 2000 registros. É poka coisa.
Eu tenho um programinha que analiza o tempo de execucao de um SQL. Eu deixei rodando um tempao aqui e foi o unico lugar no qual eu consegui obter um resultado final.
Ele me trouxe os seguintes dados c/ respeito ao tempo:
Prepare time: 21 ms (ótimo!)
Execution time: 1795592 ms (olha o problema aqui!!! Isso dá cerca de meia hora!!!! Imagine!!!)
Fetch time: 759 ms
Por favor, alguém pode me ajudar?
Grata,
Renata
Curtidas 0
Respostas
Afarias
01/08/2003
experimente as alterações a seguir:
select p.codigo,
p.descricao,
p.conta_corrente,
p.digito_conta,
p.tipo,
f.valor_pagto,
o.tipo as tipo_oper,
s.saldo_ini
from ficadptd p
left join fifluxoc f on f.cod_estab = p.cod_estab and
f.data_baixa >= :data_ini and // <-- para o WHERE
f.data_baixa <= :data_fim and // <-- para o WHERE
f.situacao = ´Baixado´ and // <-- para o WHERE
f.portador_pagto = p.codigo
left join fiopefin o on o.codigo = f.oper_financ
left join fiforpag r on r.codigo = f.forma_pagto and
r.flag_deb_cred = ´Sim´ // <-- para o WHERE
left join fisalptd s on s.cod_estab = p.cod_estab and
s.portador = p.codigo and
s.ano_mes_ref = ´200211´ // <-- para o WHERE
where p.cod_estab = :cod_estab
order by p.codigo // <-- retire (se puder fazer a ordenação no cliente)
Poste aqui seus READS e a estatística de cabeçalho do banco OIT, etc...
E qual o seu hardware (principalmente memória e HD (velocidade, tipo) e configuração de cache e page size.
T+
select p.codigo,
p.descricao,
p.conta_corrente,
p.digito_conta,
p.tipo,
f.valor_pagto,
o.tipo as tipo_oper,
s.saldo_ini
from ficadptd p
left join fifluxoc f on f.cod_estab = p.cod_estab and
f.data_baixa >= :data_ini and // <-- para o WHERE
f.data_baixa <= :data_fim and // <-- para o WHERE
f.situacao = ´Baixado´ and // <-- para o WHERE
f.portador_pagto = p.codigo
left join fiopefin o on o.codigo = f.oper_financ
left join fiforpag r on r.codigo = f.forma_pagto and
r.flag_deb_cred = ´Sim´ // <-- para o WHERE
left join fisalptd s on s.cod_estab = p.cod_estab and
s.portador = p.codigo and
s.ano_mes_ref = ´200211´ // <-- para o WHERE
where p.cod_estab = :cod_estab
order by p.codigo // <-- retire (se puder fazer a ordenação no cliente)
Poste aqui seus READS e a estatística de cabeçalho do banco OIT, etc...
E qual o seu hardware (principalmente memória e HD (velocidade, tipo) e configuração de cache e page size.
T+
GOSTEI 0
Renata
01/08/2003
OI!
Eu não posso fazer as alterações que vc. pediu no SQL. É que se eu colocar aquelas condições no WHERE como vc. disse ele vai deixar de trazer alguns registros que ele DEVE trazer. Há casos em que o registro que eu preciso está apenas no FICADPTD, que não há nada nos outros arquivos que relacione c/ ele, mas ele deve ser trazido da mesma forma. Ao mesmo tempo que há casos que o registro do FICADPTD tem relacionamentos nos outros arquivos, entende? Por isso é obrigatório o uso das condições no LEFT JOIN.
Com respeito a máquina, é um Pentium III, c/ 128 de RAM, placa Intel, etc, etc... e o problema com certeza não é esse, pq. essa é a máquina em que trabalho e tudo funciona perfeitamente e rápido (inclusive outros SQLs como esse) Eu não consigo entender pq. esse daí tá me dando tanto trabalho...
Tem alguma outra idéia?
grata,
Eu não posso fazer as alterações que vc. pediu no SQL. É que se eu colocar aquelas condições no WHERE como vc. disse ele vai deixar de trazer alguns registros que ele DEVE trazer. Há casos em que o registro que eu preciso está apenas no FICADPTD, que não há nada nos outros arquivos que relacione c/ ele, mas ele deve ser trazido da mesma forma. Ao mesmo tempo que há casos que o registro do FICADPTD tem relacionamentos nos outros arquivos, entende? Por isso é obrigatório o uso das condições no LEFT JOIN.
Com respeito a máquina, é um Pentium III, c/ 128 de RAM, placa Intel, etc, etc... e o problema com certeza não é esse, pq. essa é a máquina em que trabalho e tudo funciona perfeitamente e rápido (inclusive outros SQLs como esse) Eu não consigo entender pq. esse daí tá me dando tanto trabalho...
Tem alguma outra idéia?
grata,
GOSTEI 0
Afarias
01/08/2003
|Eu não posso fazer as alterações que vc. pediu no SQL. É que se eu
|colocar aquelas condições no WHERE como vc. {...}
Isso me ´soa´ estranho. As cláusulas JOIN deviam conter apenas os campos q fazem é ´ligação´ entre as tabelas, pelo menos por ´definição´ -- é o q se busca na normalização do banco de dados. os ´filtros´ deveriam estar na cláusula WHERE.
|esse daí tá me dando tanto trabalho...
Já verificou a seletividade dos índices q estão sendo usados?? Quais os READS informados??
T+
|colocar aquelas condições no WHERE como vc. {...}
Isso me ´soa´ estranho. As cláusulas JOIN deviam conter apenas os campos q fazem é ´ligação´ entre as tabelas, pelo menos por ´definição´ -- é o q se busca na normalização do banco de dados. os ´filtros´ deveriam estar na cláusula WHERE.
|esse daí tá me dando tanto trabalho...
Já verificou a seletividade dos índices q estão sendo usados?? Quais os READS informados??
T+
GOSTEI 0
Renata
01/08/2003
A seletividade eu já verifiquei, mas sinceramente não sei o que fazer p/ melhorar...
Os resultados são (p/ a tabela ´problema´ no meu caso..´)
Tabela: FIFLUXOC
Chave primária -> 1,0
FIFLUXOC_DT_BAIXA_SIT_IDX -> 52,48
FIFLUXOC_PORTADOR_PAGTO_IDX -> 1200,3
O indice FIFLUXOC_PORTADOR_PAGTO_IDX eu criei exatamente p/ ver se melhorava este SQL, por isso posso excluir, mudar, etc... já os outros eu não posso mexer pq. são usados em outros lugares. O que me sugere p/ melhorá-lo?
Desculpe mas não entendi o que vc. quer dizer c/ READS, senão teria te informado.
Grata,
Os resultados são (p/ a tabela ´problema´ no meu caso..´)
Tabela: FIFLUXOC
Chave primária -> 1,0
FIFLUXOC_DT_BAIXA_SIT_IDX -> 52,48
FIFLUXOC_PORTADOR_PAGTO_IDX -> 1200,3
O indice FIFLUXOC_PORTADOR_PAGTO_IDX eu criei exatamente p/ ver se melhorava este SQL, por isso posso excluir, mudar, etc... já os outros eu não posso mexer pq. são usados em outros lugares. O que me sugere p/ melhorá-lo?
Desculpe mas não entendi o que vc. quer dizer c/ READS, senão teria te informado.
Grata,
GOSTEI 0
Afarias
01/08/2003
// FIFLUXOC_PORTADOR_PAGTO_IDX -> 1200,3
Esta seletividade é realmente alta... vc poderia experimentar DROPAR este índice ou ainda, criar um índice composto com (DT_BAIXA, PORTADOR_PAGTO)
Vale testar, más sinceramente não acho q o problema esteja ai...
** E, vc ainda não disse seus READS (leituras) das tabelas envolvidas... **
No mais, este é seu único problema de performance?? Sua configuração de CACHE está oK?? Seu servidor roda em um bom HD?? Já experimentou dar um SWEEP no banco??
T+
Esta seletividade é realmente alta... vc poderia experimentar DROPAR este índice ou ainda, criar um índice composto com (DT_BAIXA, PORTADOR_PAGTO)
Vale testar, más sinceramente não acho q o problema esteja ai...
** E, vc ainda não disse seus READS (leituras) das tabelas envolvidas... **
No mais, este é seu único problema de performance?? Sua configuração de CACHE está oK?? Seu servidor roda em um bom HD?? Já experimentou dar um SWEEP no banco??
T+
GOSTEI 0