Melhorando uma Consulta SQL em FireBird
Ola a todos estou tentado otimizar uma SQL o banco e Firebird 2.1
Tenho um SQL que está demorando muito para mostra o resultado na tabela que mais vai ser utiliza tem mais de 50.000 de registros e preciso de uma consulta que me retorne o processo e os 10 últimos andamentos desse processo (Tabela de Andamentos com index "IDX_ANDAMENTOS_PROCESSUAIS") segue abaixo o SQL
ele leva de 10 a 20 minutos e as vezes trava tudo teria como melhorar essa SQL? Como?
Tenho um SQL que está demorando muito para mostra o resultado na tabela que mais vai ser utiliza tem mais de 50.000 de registros e preciso de uma consulta que me retorne o processo e os 10 últimos andamentos desse processo (Tabela de Andamentos com index "IDX_ANDAMENTOS_PROCESSUAIS") segue abaixo o SQL
SELECT
T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
T3.CODIGO_ANDAMENTO,
T3.DATA,
T3.HORA,
T3.ATO_FATURAVEL,
T3.DESCRICAO_ANDAMENTO,
T3.OBSERV_ANDAM
FROM
PROCESSOS T1
LEFT JOIN (SELECT FIRST 10
V1.NUMERO_PROCESSO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERVACAO AS OBSERV_ANDAM
FROM
ANDAMENTOS_PROCESSUAIS V1,
PROCESSOS V2
WHERE
V1.NUMERO_PROCESSO = V2.NUMERO_PROCESSO
ORDER BY V1.CODIGO_ANDAMENTO DESC) T3 ON T1.NUMERO_PROCESSO = T3.NUMERO_PROCESSO,
CLIENTES T2
WHERE T1.COD_CLIENTE = T2.COD_CLIENTE
ele leva de 10 a 20 minutos e as vezes trava tudo teria como melhorar essa SQL? Como?
Eduardo Mendonça
Curtidas 0
Respostas
Ruy Salles
16/01/2016
Eduardo, não sei se irá resolver, pois a performance do banco também depende muito da modelagem, mas vai uma sugestão:
SELECT
FIRST 10 T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERV_ANDAM
FROM
PROCESSOS T1
LEFT JOIN ANDAMENTOS_PROCESSUAIS V1
ON V1.NUMERO_PROCESSO = T1.NUMERO_PROCESSO
INNER JOIN CLIENTES T2
ON T1.COD_CLIENTE = T2.COD_CLIENTE
ORDER BY V1.CODIGO_ANDAMENTO DESC
espero ter ajudado
SELECT
FIRST 10 T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERV_ANDAM
FROM
PROCESSOS T1
LEFT JOIN ANDAMENTOS_PROCESSUAIS V1
ON V1.NUMERO_PROCESSO = T1.NUMERO_PROCESSO
INNER JOIN CLIENTES T2
ON T1.COD_CLIENTE = T2.COD_CLIENTE
ORDER BY V1.CODIGO_ANDAMENTO DESC
espero ter ajudado
GOSTEI 0
Eduardo Mendonça
16/01/2016
Fiz o Teste aqui Com o SQl que acima ele funciona normal só que ... Não traz o que eu preciso eu preciso que traga pelo menos os 10 últimos andamentos de cada processo.
GOSTEI 0
Ruy Salles
16/01/2016
Tente isso:
SELECT
T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERV_ANDAM
FROM
PROCESSOS T1
LEFT JOIN ANDAMENTOS_PROCESSUAIS V1
ON V1.NUMERO_PROCESSO = T1.NUMERO_PROCESSO
AND V1.CODIGO_ANDAMENTO IN (SELECT FIRST 1O CODIGO_ANDAMENTO
FROM ANDAMENTOS_PROCESSUAIS V2
WHERE V2.CODIGO_ANDAMENTO = V1.CODIGO_ANDAMENTO
ORDER BY V2.CODIGO_ANDAMENTO DESC)
INNER JOIN CLIENTES T2
ON T1.COD_CLIENTE = T2.COD_CLIENTE
Espero ter ajudado
SELECT
T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERV_ANDAM
FROM
PROCESSOS T1
LEFT JOIN ANDAMENTOS_PROCESSUAIS V1
ON V1.NUMERO_PROCESSO = T1.NUMERO_PROCESSO
AND V1.CODIGO_ANDAMENTO IN (SELECT FIRST 1O CODIGO_ANDAMENTO
FROM ANDAMENTOS_PROCESSUAIS V2
WHERE V2.CODIGO_ANDAMENTO = V1.CODIGO_ANDAMENTO
ORDER BY V2.CODIGO_ANDAMENTO DESC)
INNER JOIN CLIENTES T2
ON T1.COD_CLIENTE = T2.COD_CLIENTE
Espero ter ajudado
GOSTEI 0
Marcos P
16/01/2016
LEFT JOIN a partir de subquery é muito oneroso para o banco !
Tente adaptar sua consulta a algo mais direto, conforme sugerido pelo Ruy, ou utilize uma tabela temporária para auxiliá-lo.
Outra coisa que pode ajudar é revisar a estrutura de índices que atende essa sua consulta.
Eventualmente, criar índices específicos para suportar esse consulta, pode ser uma boa estratégia.
Tente adaptar sua consulta a algo mais direto, conforme sugerido pelo Ruy, ou utilize uma tabela temporária para auxiliá-lo.
Outra coisa que pode ajudar é revisar a estrutura de índices que atende essa sua consulta.
Eventualmente, criar índices específicos para suportar esse consulta, pode ser uma boa estratégia.
GOSTEI 0
Alex Lekao
16/01/2016
pensei que ele poderia montar uma view para ter os dados basicos e depois fazer a manipulacao desta view para ter o resultado final.
Ou usar um select que traz os dados principais e depois um outro select para manipular os dados para o resultado final(esqueci o nome dado a isso. rsrsr).
Basicamente Assim:
nao sei se me fiz entender, desculpe se atrapalhei.
Ou usar um select que traz os dados principais e depois um outro select para manipular os dados para o resultado final(esqueci o nome dado a isso. rsrsr).
Basicamente Assim:
SELECT
T1.CAMPO,
T1.CAMPO2,
T1.CAMPO*CAMPO2 AS TOTAL
FROM (SELECT
CAMPO,
CAMPO2,
CAMPO3,
CAMPO4
FROM TABELA
WHERE X = Y
) AS T1
WHERE Z > 1
nao sei se me fiz entender, desculpe se atrapalhei.
GOSTEI 0
Eduardo Mendonça
16/01/2016
Vou testar e mais tarde eu posto os resultados
GOSTEI 0
Huidemar Costa
16/01/2016
Veja se assim funciona
with t3 as (
SELECT FIRST 10
V1.NUMERO_PROCESSO,
V1.CODIGO_ANDAMENTO,
V1.DATA,
V1.HORA,
V1.ATO_FATURAVEL,
V1.DESCRICAO_ANDAMENTO,
V1.OBSERVACAO AS OBSERV_ANDAM
FROM
ANDAMENTOS_PROCESSUAIS V1 inner join PROCESSOS V2 on (V1.NUMERO_PROCESSO = V2.NUMERO_PROCESSO)
ORDER BY V1.CODIGO_ANDAMENTO DESC
)
SELECT
T1.NUMERO_PROCESSO,
T1.DATA_ESCRITORIO,
T1.STATUS,
T1.TITULO_DESCRICAO,
T2.NOME_CLIENTE,
T2.NOME_UNIDADE,
T1.PARTE_CONTRARIA,
T1.ADVOGADO_DILIGENTE,
T1.ADVOGADO_PARTE_CONTRARIA,
T1.TIPO_ACAO1 AS TIPO_ACAO,
T1.FASE_PROCESSO,
T1.OBSERVACAO,
T3.CODIGO_ANDAMENTO,
T3.DATA,
T3.HORA,
T3.ATO_FATURAVEL,
T3.DESCRICAO_ANDAMENTO,
T3.OBSERV_ANDAM
FROM
PROCESSOS T1 LEFT JOIN T3 ON (T1.NUMERO_PROCESSO = T3.NUMERO_PROCESSO)
inner join CLIENTES T2 on (T1.COD_CLIENTE = T2.COD_CLIENTE)
GOSTEI 0