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