Atualmente, estou lendo um livro do SQL Server 2014. Ele, como todas as outras fontes online que encontrei, informa que é PERCENTILE_CONT
uma maneira muito lenta de calcular medianas e não mostra o plano de execução supostamente péssimo. Ainda é PERCENTILE_CONT
extremamente lento nesta tarefa nas versões recentes (ou seja, 2022 ou posteriores) do SQL Server?
"Extremamente lento" é subjetivo, portanto, mostrar que os planos de execução não mudam entre o SQL Server 2014 e 2022 será suficiente. Eu mesmo verificaria isso, mas o servidor mais novo que tenho está na versão de 2012.
Presumo que uma das fontes online a que você se refere seja Qual é a maneira mais rápida de calcular a mediana?
"2012_A" e "2012_B" abaixo referem-se às consultas desse artigo.
Usando dados de teste semelhantes...
2012_A com nível de compatibilidade 2014
Tentar a mesma instância do SQL Server 2022 como os testes subsequentes, mas com o nível de compatibilidade de 120 (SQL Server 2014) levou 1 minuto e 56 segundos
2012_A em 2022
No SQL Server 2019+, o plano de execução agora pode usar agregações janeladas em modo de lote e isso foi consideravelmente mais rápido que o esforço anterior, com um tempo decorrido de 7,5 segundos, mas ainda é mais lento que o método mais rápido proposto naquele artigo (talvez atualize este método de "terrível" para "ruim") .
PERCENTILE_CONT
é implementado como uma função analítica e todas as 10.000.000 linhas de origem são colocadas em spool no Window Aggregate à direita para que possam ter o resultado adicionado a elas assim que for calculado. Isso é inerentemente intensivo em recursos.PERCENTILE_CONT
não pôde ser implementado como um agregado de streaming porque você precisa ler todo o stream para obter a contagem e, assim, conhecer as linhas de seu interesse.O método "vencedor" do artigo SQL Performance ainda vence em 2022 - com um tempo decorrido de cerca de 1 segundo.
2012_B
Resultado Aproximado
O SQL Server 2022 inclui uma nova função agregada
APPROX_PERCENTILE_CONT
. Como esta é uma função agregada, não requer umaOVER
cláusula - ou o queTOP 1
adicionei àPERCENTILE_CONT
consulta acimaEmbora o tempo decorrido tenha sido competitivo com 2012_B, no geral, ele usou muito mais tempo de CPU e, além disso, retorna apenas uma aproximação do resultado correto - portanto, para este teste, eu ainda preferiria 2012_B
É sim. Nenhuma das facilidades de percentil é especificamente otimizada para o caso mediano. A natureza geral da implementação (para qualquer percentil, não apenas 0,5) significa que ela é mais flexível, mas menos eficiente do que poderia ser uma função ou agregação de janela somente mediana específica.
Usando os dados de teste de Martin, descobri que 2012_B foi executado em cerca de 400ms :
Isso pode ser aprimorado no nível de compatibilidade 150 (SQL Server 2019) ou posterior usando o modo de lote no Rowstore (BMOR) por meio de uma expressão diferente do mesmo algoritmo básico:
Essa implementação é executada em cerca de 275 ms , com todas as operações caras usando o processamento em lote (destaque em azul).
Observação BMOR requer Enterprise Edition ou equivalente.