Eu me deparei com essa pergunta em uma conversa no Twitter com Lukas Eder .
Embora o comportamento correto seja aplicar a cláusula ORDER BY na consulta mais externa, porque, aqui, não estamos usando DISTINCT, GROUP BY, JOIN ou qualquer outra cláusula WHERE na consulta mais externa, por que um RDBMS não passaria o dados recebidos como foram classificados pela consulta interna?
SELECT *
FROM (
SELECT * FROM table ORDER BY time DESC
) AS t
Ao executar este exemplo no PostgreSQL, pelo menos, você obtém o mesmo Plano de Execução para a consulta interna e para o exemplo da tabela derivada, além do mesmo conjunto de resultados.
Portanto, suponho que o Planejador simplesmente descarte a consulta mais externa porque é redundante ou simplesmente passa pelos resultados da tabela interna.
Alguém acha que isso pode não ser o caso?
fonte
ORDER BY
leadinternopara otimização diferente para máx . Em grupoRespostas:
A maioria dos bancos de dados é bastante clara sobre o fato de que uma
ORDER BY
subconsulta é:TOP
ouOFFSET .. FETCH
)OFFSET .. FETCH
ouLIMIT
)Aqui está um exemplo do manual do DB2 LUW (ênfase minha)
A redação é bastante explícita, assim como no PostgreSQL :
A partir dessa especificação, pode-se concluir que qualquer pedido resultante da
ORDER BY
cláusula em uma tabela derivada é meramente acidental e pode coincidir com o pedido esperado (o que ocorre na maioria dos bancos de dados em seu exemplo trivial), mas não seria prudente confiar em isto.Nota lateral no DB2:
Em particular, o DB2 possui um recurso menos conhecido chamado
ORDER BY ORDER OF <table-designator>
, que pode ser usado da seguinte maneira:Nesse caso em particular, a ordem da tabela derivada pode ser explicitamente reutilizada na classe SELECT mais externa.
Nota lateral no Oracle:
Durante anos, é uma prática do Oracle implementar a
OFFSET
paginação usandoROWNUM
, que só pode ser calculada razoavelmente após o pedido de uma tabela derivada:Pode-se razoavelmente esperar que, pelo menos na presença de
ROWNUM
uma consulta, as futuras versões do Oracle não quebrem esse comportamento para não quebrar praticamente todo o Oracle SQL herdado, que ainda não migrou para o muito mais desejável eOFFSET .. FETCH
sintaxe padrão legível do SQL :fonte
Meaningless: E.g. PostgreSQL
realmente deve ser: 'confiável', porque ele faz significar alguma coisa. As linhas são classificadas na consulta interna e essa ordem é mantida em níveis de consulta externos, a menos que seja instruído de outra forma ou que seja reordenado oportuno para operações adicionais. Mesmo que seja apenas um detalhe de implementação, não faz sentido. Isso pode ser usado para entrada classificada para agregar funções. Os mesmo dicas manuais como muito:Alternatively, supplying the input values from a sorted subquery will usually work.
ORDER BY
.Sim. Sem uma
ORDER BY
cláusula, a ordem de saída é indefinida e o planejador de consultas está dentro do seu alcance para assumir que você sabe e entende isso.Ele pode decidir que, como a consulta externa não especifica uma ordem, ela pode descartar a ordem na consulta interna para evitar uma operação de classificação, especialmente se não houver um índice clusterizado ou nenhum índice para dar suporte à ordem. Se não o fizer agora , poderá funcionar em versões futuras.
Nunca confie em comportamento indefinido. Se você precisar de um pedido específico, forneça uma
ORDER BY
cláusula no local apropriado.fonte
TOP 100%
para que a consulta atual não seja portátil, isso deve ser uma prioridade para o seu projeto. Como o Postgres obedece à ordem na consulta interna agora não significa que sempre será no futuro (ou que versões mais antigas, de fato), assim você deve evitar depender do comportamento apenas no caso.ORDER BY
é MariaDB: Por que ORDER BY em uma subconsulta FROM é ignorado?É o mesmo problema de comportamento indefinido - funciona para você, funciona para mim, reformata o HDD em prod;)
Podemos dar um passo atrás e dizer que, em certo sentido, você está certo - não há razão terrena para que um RDBMS sano reorganize as linhas na seleção interna. Mas isso não é garantido - o que significa que, no futuro, pode haver uma razão, e os fornecedores são livres para fazê-lo. Significando que qualquer código que se baseia nesse comportamento está à mercê de uma alteração que um fornecedor poderia fazer e que não teria obrigação de divulgar, pois não é uma alteração de quebra de um API POV.
fonte
SELECT
semORDER BY
realmente é não determinística, e não apenas na teoria ou porque os dados alterados.)A resposta para todas as versões existentes do Postgres (que você estava testando) é: Não - para esta consulta específica. A ordem de classificação é garantida.
O pessoal do servidor SQL ficará desconfortável com isso, pois a Microsoft nem permite
ORDER BY
subconsultas. No entanto, a ordem de classificação é garantida para essa consulta simples no Postgres.ORDER BY
é aplicado na subconsulta e a consulta externa não faz nada que possa alterar a ordem.O manual até sugere isso no capítulo Funções agregadas :
Observe que isso é verdade apenas enquanto os níveis de consulta externa não adicionam operações que podem alterar a ordem. Portanto, é apenas "garantido" para o caso simples, e isso não é suportado pelo padrão SQL. O Postgres pode reordenar se for oportuno para operações adicionais. Em caso de dúvida, adicione outro
ORDER BY
ao exteriorSELECT
. (Nesse caso, o interiorORDER BY
seria um ruído redundante para esta consulta simples.)fonte
"table"
não é uma tabela base simples, mas uma visão complexa ou uma tabela particionada? É verdade quando o plano também tem execução paralela? Também é verdade no Postgres 10? (Eu só estou pedindo, eu não tenho certeza que a resposta de qualquer destas perguntas.)