随查询变化缓慢的分组依据

时间:2019-05-08 22:33:35

标签: sql postgresql performance postgresql-9.6

我们有一个带有多个子查询的查询,每个子查询都包含一个group by。 在只读数据库中运行时,其处理速度较快;而在读写数据库中运行时,其访问量很少,处理速度则特别慢。 我想要优化此查询的提示。

带有Ubuntu Linux Server版本14.04.6的Postgresql版本9.6

SELECT DISTINCT

  TO_CHAR(Viagem.date, 'DD/MM/YYYY HH24:MI:SS')     AS Data_Solicitacao,

  Viagem.id AS NumeroSolicitacao,

  CASE Viagem.status WHEN 'A' THEN 'Aprovada'

                                                 WHEN 'I' THEN 'Iniciada'

                                                 WHEN 'F' THEN 'Finalizada'

                                                 WHEN 'S' THEN 'Sinistrada'

                                                 WHEN 'I' THEN 'Iniciada'

                                                 WHEN 'P' THEN 'Pendente'

                                                 WHEN 'O' THEN 'Solicitada'

                                                 WHEN 'C' THEN 'Cancelada'

                                                 WHEN 'R' THEN 'Reencaminhada'

                                                 WHEN 'N' THEN 'Nao Aprovada'

                                                 WHEN 'V' THEN 'Parado'

                                                 ELSE 'Desconhecido'

                 END AS Status,
        Base.nome AS Base,
        Base.software AS Tecnologia,
  usuario_cadastrador AS "Usuario cadastrador",
  TO_CHAR(usuario_cadastrador.data , 'DD/MM/YYYY HH24:MI:SS') AS "Data de cadastro",
        usuario_aprovador.operador AS "Usuario aprovador",
        TO_CHAR(usuario_aprovador.data , 'DD/MM/YYYY HH24:MI:SS') AS "Data aprovacao",
        usuario_finalizador.operador AS "Usuario finalizador",
        TO_CHAR(usuario_finalizador.data, 'DD/MM/YYYY HH24:MI:SS')  AS "Data do finalizador",
        Empresa.nome AS Empresa, 
  Localidade.nome AS Localidade,
        PontoOrigem2.nome      AS Origem,
        EnderecoOrigem.cidade  AS Cidade_origem,
        EnderecoOrigem.Estado  AS UF_origem,
        PontoDestino.nome      AS Destino,
        EnderecoDestino.cidade AS Cidade_destino,
        EnderecoDestino.Estado AS UF_destino,

  TO_CHAR(Origem.dataSaidaPrevista, 'DD/MM/YYYY HH24:MI:SS')    AS InicioPrevisto,

  TO_CHAR(Origem.datasaidarealizada, 'DD/MM/YYYY HH24:MI:SS')        AS SaidaReal,

  TO_CHAR(Destino.dataChegadaPrevista,'DD/MM/YYYY HH24:MI:SS') AS TerminoPrevisto,

  TO_CHAR(Destino.datachegadarealizada, 'DD/MM/YYYY HH24:MI:SS')     AS ChegadaReal,

        TO_CHAR((Destino.datachegadarealizada - Origem.datasaidarealizada), 'HH24:MI:SS') AS "Duracao da viagem ",

  Viagem.manifesto AS Manifesto,

  Automovel.placa AS Placa,

  CASE Pesquisaauto.vinculo WHEN 'F' THEN 'Frota'

                                  WHEN 'A' THEN 'Agregado' 

                                  WHEN 'G'  THEN 'Agregado_motorista'

          WHEN 'T'  THEN 'Terceiro'

                                ELSE 'Desconhecido'

               END  AS Vinculo_Auto,

  Pessoa.nome AS MotoristaNome,

                Pessoa.cpfcnpj AS CPF,

  CASE Pesquisamot.vinculo WHEN 'F' THEN 'Frota'

                                                      WHEN 'A' THEN 'Agregado' 

                                                      WHEN 'T' THEN 'Terceiro'

            WHEN 'J'  THEN 'Ajudante'   

            WHEN 'G'  THEN 'Agregado_motorista'

            WHEN 'U'  THEN 'Funcionario'

            ELSE 'Desconhecido'

               END  AS Vinculo,

--               tp.nome AS Produto,
               concattipoproduto(Viagem.id) AS Produto,

               somadocumentos(Viagem.id) AS Valor_transportado




FROM Automovel 

LEFT JOIN Viagem ON Viagem.veiculo_id = Automovel.id

LEFT JOIN (select min(motoristas_id), viagem_id from Viagem_Motorista group by viagem_id) AS PrimeiroMotorista ON PrimeiroMotorista.viagem_id = Viagem.id

LEFT JOIN Empresa ON Viagem.empresa_id = Empresa.id

LEFT JOIN Motorista ON Motorista.id = PrimeiroMotorista.min

LEFT JOIN Pessoa ON Pessoa.id = Motorista.pessoa_id

LEFT JOIN (select f.ordem, f.viagem_id, f.ponto_id, f.dataSaidaPrevista, f.datasaidarealizada from (select viagem_id, min(ordem) from elementoviagem group by viagem_id) as x inner join elementoviagem f on f.ordem = x.min and f.viagem_id = x.viagem_id) as Origem on Origem.viagem_id = Viagem.id

LEFT JOIN pontoviagem PontoOrigem ON PontoOrigem.id = Origem.ponto_id
LEFT JOIN endereco EnderecoOrigem ON EnderecoOrigem.id = PontoOrigem.endereco_id

LEFT JOIN (select f.ordem, f.viagem_id, f.ponto_id, f.dataChegadaPrevista, f.datachegadarealizada from (select viagem_id, max(ordem) from elementoviagem group by viagem_id) as x inner join elementoviagem f on f.ordem = x.max and f.viagem_id = x.viagem_id) as Destino on Destino.viagem_id = Viagem.id

LEFT JOIN pontoviagem PontoDestino ON PontoDestino.id = Destino.ponto_id
LEFT JOIN endereco EnderecoDestino ON EnderecoDestino.id = PontoDestino.endereco_id

LEFT JOIN ElementoViagem ev ON ev.viagem_id = Viagem.id

LEFT JOIN documento ON documento.elementoviagem_id = ev.id

--LEFT JOIN tipoproduto tp  ON tp.id = documento.tipoproduto_id 

LEFT JOIN (select max(id), empresa_id, motorista_id from Pesquisa group by empresa_id, motorista_id) AS UltimaPesquisa ON UltimaPesquisa.motorista_id = Motorista.id and UltimaPesquisa.empresa_id = Viagem.empresa_id

LEFT JOIN Pesquisa Pesquisamot on Pesquisamot.id = UltimaPesquisa.max

LEFT JOIN (select max(id), empresa_id, veiculo_id from Pesquisa group by empresa_id, veiculo_id) AS UltimaPesquisaVeiculo ON UltimaPesquisaVeiculo.veiculo_id = Automovel.id and UltimaPesquisaVeiculo.empresa_id = Viagem.empresa_id

LEFT JOIN Pesquisa pesquisaauto ON pesquisaauto.id = UltimaPesquisaVeiculo.max
LEFT JOIN Localidade on Viagem.localidade_id=Localidade.id
left join (select f.ordem, f.viagem_id, f.ponto_id, f.dataSaidaPrevista from (select viagem_id, min(ordem) from elementoviagem group by viagem_id)
AS x inner join elementoviagem f on f.ordem = x.min and f.viagem_id = x.viagem_id) as
Origem2 on Origem2.viagem_id = Viagem.id left join pontoviagem PontoOrigem2 on PontoOrigem2.id = Origem.ponto_id
LEFT JOIN (select f.ordem, f.viagem_id, f.ponto_id, f.dataChegadaPrevista from (select viagem_id, max(ordem)
from elementoviagem group by viagem_id) as x inner join elementoviagem f on f.ordem = x.max and
f.viagem_id = x.viagem_id) as Destino2 on Destino2.viagem_id = Viagem.id
LEFT JOIN viagem_documento ON viagem_documento.viagem_id = Viagem.id
--LEFT JOIN (SELECT SUM(valor) AS total, id FROM documento GROUP BY id) AS documentovalor ON documentovalor.id = viagem_documento.documentostransferencia_id 
--LEFT JOIN (SELECT SUM(valor) AS total, evg.viagem_id FROM documento doc INNER JOIN  elementoviagem evg ON doc.elementoviagem_id = evg.id GROUP BY evg.viagem_id) AS documentovalorcoleta ON  documentovalorcoleta.viagem_id = Viagem.id

LEFT JOIN Base ON Base.id = Viagem.base_id
--LEFT JOIN (SELECT h.viagem_id, Max(h.data) AS data, u.nome as operador FROM historicoviagem h INNER JOIN usuario u ON h.usuario_id = u.id  WHERE acao = 'A'GROUP BY h.viagem_id, data, u.nome) AS usuario_aprovador ON usuario_aprovador.viagem_id = Viagem.id
LEFT JOIN (SELECT viagem_id, MAX(data) AS data, u.nome AS operador FROM historicoviagem h INNER JOIN usuario u ON u.id = h.usuario_id
                                                                   WHERE acao = 'C' GROUP BY viagem_id, u.nome) AS usuario_cadastrador ON usuario_cadastrador.viagem_id = Viagem.id 
LEFT JOIN (SELECT viagem_id, MAX(data) AS data, u.nome AS operador FROM historicoviagem h INNER JOIN usuario u ON u.id = h.usuario_id 
                                                                   WHERE acao = 'A' GROUP BY viagem_id, u.nome) AS usuario_aprovador ON usuario_aprovador.viagem_id = Viagem.id
--LEFT JOIN (SELECT h.viagem_id, h.data, u.nome as operador FROM historicoviagem h INNER JOIN usuario u ON h.usuario_id = u.id  WHERE acao IN('F','L','R') ) AS usuario_finalizador ON usuario_finalizador.viagem_id = Viagem.id
LEFT JOIN (SELECT va.viagem_id, MAX(av.data) as data, u.nome as operador FROM acaoviagemselecionada av INNER JOIN usuario u ON av.usuario_id = u.id  LEFT JOIN viagem_acaoviagemselecionada va ON va.acoes_id = av.id  WHERE av.acao_id = 5 GROUP BY va.viagem_id, u.nome) AS usuario_finalizador ON usuario_finalizador.viagem_id = Viagem.id

WHERE Empresa.ativado = true AND Viagem.date BETWEEN '2019-4-1 00:00:00' AND '2019-4-30 23:59:59'
ORDER BY Data_solicitacao;

我希望在读写数据库中得到更快的结果。

0 个答案:

没有答案