Eu tenho uma consulta que é um pouco mais lenta.
SELECT b.BreakdownClassificationId,
k.IsinCode,
k.SedolCode,
ClassificationDate,
NAME,
InstrumentType,
GeographicalLocation,
CapSize,
Currency,
ExchangeName,
HoldingDomicile,
MaturityDate,
Sector,
MajorSector
FROM #BreakdownSet b
OUTER apply (SELECT TOP 1 IsinCode,
SedolCode,
ClassificationDate,
NAME,
InstrumentType,
GeographicalLocation,
CapSize CapSize,
Currency,
ExchangeName,
HoldingDomicile,
MaturityDate,
Sector,
MajorSector
FROM dbfinex.dbo.PfPortfolioHoldingClassificationFtid x WITH (nolock)
WHERE ( x.isincode > ''
AND x.isincode = b.breakdowncode )
OR ( x.sedolcode > ''
AND x.sedolcode = b.breakdowncode )
OR ( x.sedolcode > ''
AND x.sedolcode = b.sedolcode )
OR ( x.isincode > ''
AND x.isincode = b.isincode )
ORDER BY CASE
WHEN x.sedolcode = b.breakdowncode THEN 1
WHEN x.isincode = b.breakdowncode THEN 2
WHEN x.sedolcode = b.sedolcode THEN 3
WHEN x.isincode = b.isincode THEN 4
ELSE 5
END,
classificationdate DESC) k
Plano de execução
Order By
dentro do Cross Apply
é muito caro, existe alguma maneira melhor de escrever essa consulta?
Você pode eliminar a classificação, se desejar, embora seja difícil dizer se isso melhorará o desempenho da consulta. A chave é como você construiu sua
ORDER BY
cláusula junto com as condições de pesquisa. Se houver alguma linha que correspondax.sedolcode = b.breakdowncode
, você deseja pegar essa linha, caso contrário, você vai para a próxima condição. Com os índices corretos, podemos evitar a classificação dividindo os arquivosAPPLY
. O otimizador de consulta do SQL Server realmente dá uma boa dica porque transforma suasOR
condições emUNION
s.Vou criar um exemplo limitado para mostrar a forma geral do plano de consulta que procuro. Também assumirei que a
PfPortfolioHoldingClassificationFtid
tabela tem uma chave primária e uma chave de cluster em umaPK
coluna. Aqui estão meus dados de teste:Aqui está sua consulta com minhas definições de tabela:
Não surpreendentemente eu recebo um plano diferente do seu, mas o tipo ainda tem um alto custo estimado. E se dividirmos
APPLY
em quatro partes e cadaAPPLY
uma retornar apenas a chave primária da tabela? Se tivermos um índice de cobertura para cada umAPPLY
, podemos encontrar a chave primária da linha correspondente com no máximo quatro buscas de índice. Nenhuma classificação é necessária. Também podemos pular as buscas que não precisamos adicionando filtros nosAPPLY
s, mas isso não é um comportamento garantido. Aqui está uma maneira de escrevê-lo:Com 1,5 milhão de linhas na tabela temporária, o pior caso possível deve ser 6 milhões de buscas de índice não clusterizado e 1,5 milhão de buscas de índice clusterizado.
A consulta é executada em dois segundos na minha máquina. O tempo de execução não importa porque tenho dados sem sentido. No entanto, não há um tipo no plano. Carreguei o plano de consulta para Paste The Plan . Você deve considerar fazer isso também para perguntas futuras. Aqui está também uma captura de tela do plano real:
A consulta que você tem faz uma junção de loop aninhada e não fica paralela. Com
LOOP JOIN
eMAXDOP 1
dicas a consulta termina em sete segundos na minha máquina. Aqui está o plano e aqui está uma captura de tela: