Pergunta

Eu fui inspirado pelas boas respostas do meu anterior pergunta Sobre SQL. Agora, este SQL é executado em um db com o Interbase 2009. É de cerca de 21 GB de tamanho.

SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
       and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc

Existem 840000 linhas com linhas addrdistance 190000 com endereço e 4 com o DOURSOQUERYTASK.

A questão é: isso pode ser feito mais rápido? Eu acho, a mesma consulta é executada muitas vezes Selecione Bold_Id de DistanceyTask. Observe que não estou interessado em procedimentos armazenados, apenas SQL simples :)

Edit1 Aqui está o plano de execução atual:

Statement: SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
       and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc

PLAN (DISTANCEQUERYTASK INDEX (RDB$PRIMARY218))
PLAN SORT (JOIN (JOIN (ADDRDISTANCE NATURAL,ADDRESSFROM INDEX (RDB$PRIMARY234)),ADDRESSTO INDEX (RDB$PRIMARY234)))

E sim, o DOURSQUERYTASK deve ter um número baixo se linhas no banco de dados.

Foi útil?

Solução

Usar a junção esquerda e as subconsminações desacelerará qualquer consulta.

Você pode obter algumas melhorias com os índices corretos (em Bold_id, Distancemeter, PseudodistanCeasCostkm) Lembre -se de que mais índices aumentam o tamanho do banco de dados

Outras dicas

Suponho que Bold_Id é a sua chave e, portanto, devidamente indexado.
Em seguida, substituir o subseleto e o não ... por uma junção pode ajudar o otimizador.

SELECT DistanceAsMeters, Bold_Id, Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
LEFT JOIN DistanceQueryTask ON AddrDistance.bold_id = DistanceQueryTask.bold_id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
  and DistanceQueryTask.bold_id is null
Order By Created Desc

Crie um índice para esta parte: (DistancEasMeters = 0 e PseudodistanCeascostkm = 0) porque faz uma (Bad) Tabela Scan para ele: Addrdistance Natural Natural

E tente usar a junção em vez de subseleção, conforme declarado pelo François.

Como Daniel e Andre Sugers, um índice ajuda muito.
Eu sugeriria que esse índice (Distancemeter, PseudodistanCeascostkm, Bold_id), porque as duas primeiras partes do índice são constantes, então é uma parte smal do índice que é necessário para ler.

Se for um fato que a FromAddress e/ou a Toaddress existem, você pode alterar a junção esquerda para a junção interna, porque geralmente é mais rápida (o otimizador de consulta pode fazer algumas suposições).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top