Me topé con esta pregunta en una conversación de Twitter con Lukas Eder .
Aunque el comportamiento correcto sería aplicar la cláusula ORDER BY en la consulta más externa, porque, aquí, no estamos utilizando DISTINCT, GROUP BY, JOIN o cualquier otra cláusula WHERE en la consulta más externa, ¿por qué un RDBMS no pasaría la datos entrantes como fueron ordenados por la consulta interna?
SELECT *
FROM (
SELECT * FROM table ORDER BY time DESC
) AS t
Al ejecutar este ejemplo en PostgreSQL, al menos, obtiene el mismo Plan de ejecución para la consulta interna y este ejemplo de tabla derivada, así como el mismo conjunto de resultados.
Entonces, supongo que el Planificador simplemente descartará la consulta más externa porque es redundante o simplemente pasará los resultados de la tabla interna.
¿Alguien piensa que este podría no ser el caso?
fuente
ORDER BY
cableinternoa una optimización diferente para groupwise max .Respuestas:
La mayoría de las bases de datos son bastante claras sobre el hecho de que un
ORDER BY
en una subconsulta es:TOP
oOFFSET .. FETCH
)OFFSET .. FETCH
oLIMIT
)Aquí hay un ejemplo del manual de DB2 LUW (énfasis mío)
La redacción es bastante explícita, al igual que PostgreSQL :
A partir de esta especificación, se puede seguir que cualquier orden resultante de la
ORDER BY
cláusula en una tabla derivada es meramente accidental y puede coincidir coincidentemente con su orden esperado (lo que hace en la mayoría de las bases de datos en su ejemplo trivial), pero sería imprudente confiar en esta.Nota al margen sobre DB2:
En particular, DB2 tiene una característica menos conocida llamada
ORDER BY ORDER OF <table-designator>
, que se puede utilizar de la siguiente manera:En este caso particular, el orden de la tabla derivada se puede reutilizar explícitamente en el exterior más SELECCIONAR
Nota al margen sobre Oracle:
Durante años ha sido una práctica en Oracle implementar el
OFFSET
uso de la paginaciónROWNUM
, que puede calcularse razonablemente solo después de ordenar una tabla derivada:Se puede esperar razonablemente que, al menos en presencia de
ROWNUM
una consulta, las futuras versiones de Oracle no rompan este comportamiento para no romper casi todo el Oracle SQL heredado que aún no se ha migrado a los más deseables y deseados.OFFSET .. FETCH
sintaxis estándar de SQL legible :fuente
Meaningless: E.g. PostgreSQL
en realidad debería ser: 'poco fiables', ya que lo hace significar algo. Las filas se ordenan en la consulta interna, y ese orden se mantiene en los niveles de la consulta externa, a menos que se indique lo contrario o el reordenamiento sea oportuno para operaciones adicionales. Incluso si eso es solo un detalle de implementación, no tiene sentido. Esto se puede usar para entradas ordenadas para agregar funciones. El manual incluso da pistas:Alternatively, supplying the input values from a sorted subquery will usually work.
ORDER BY
.Si. Sin una
ORDER BY
cláusula, el orden de salida no está definido y el planificador de consultas está dentro de su alcance para asumir que usted lo sabe y lo comprende.Puede decidir que debido a que la consulta externa no especifica un orden, puede descartar el orden en la consulta interna para evitar una operación de clasificación, especialmente si no hay un índice agrupado o ningún índice para admitir el orden. Si no lo hace ahora , puede hacerlo en futuras versiones.
Nunca confíes en un comportamiento indefinido. Si necesita un pedido específico, proporcione una
ORDER BY
cláusula en el lugar apropiado.fuente
TOP 100%
para que la consulta actual no sea portátil, si esa es una prioridad para su proyecto. Dado que Postgres obedece el pedido en la consulta interna ahora, no implica que siempre lo hará en el futuro (o que las versiones anteriores hacen, de hecho) por lo que debe evitar depender de la conducta por si acaso.ORDER BY
es MariaDB: ¿Por qué se ignora ORDER BY en una subconsulta FROM?Es el problema con el comportamiento indefinido: funciona para usted, funciona para mí, formatea el HDD en prod;)
Podemos dar un paso atrás y decir que, en cierto sentido, tiene razón: no hay ninguna razón terrenal por la que un RDBMS sensato reorganice las filas en la selección interna. Pero no está garantizado, lo que significa que en el futuro puede haber una razón, y los proveedores son libres de hacerlo. Lo que significa que cualquier código que se base en este comportamiento está a merced de un cambio que un proveedor podría hacer y que no estaría obligado a publicar, ya que no es un cambio importante de un POV API.
fuente
SELECT
sin laORDER BY
verdad es no determinista, y no sólo en teoría o porque los datos cambiados.)La respuesta para todas las versiones existentes de Postgres (que estaba probando) es: No , para esta consulta en particular. El orden de clasificación está garantizado.
La gente del servidor SQL se sentirá incómoda con esto ya que Microsoft ni siquiera permite
ORDER BY
subconsultas. No obstante, el orden de clasificación está garantizado para esta consulta simple en Postgres.ORDER BY
se aplica en la subconsulta y la consulta externa no hace nada que pueda cambiar el orden.El manual incluso lo insinúa en el capítulo Funciones agregadas :
Tenga en cuenta que esto solo es cierto mientras que los niveles de consulta externos no agregan operaciones que puedan cambiar el orden. Por lo tanto, solo está "garantizado" para el caso simple, y eso no está respaldado por el estándar SQL. Postgres es libre de reordenar si es oportuno para operaciones adicionales. En caso de duda agregue otro
ORDER BY
al exteriorSELECT
. (En cuyo caso, elORDER BY
ruido interno sería redundante para esta simple consulta).fuente
"table"
no se trata de una tabla básica simple sino de una vista compleja o una tabla particionada? ¿Es cierto cuando el plan también tiene ejecución paralela? ¿Es cierto también en Postgres 10? (Sólo te pido, no estoy seguro de la respuesta de cualquiera de estas preguntas.)