Implementaciones de bases de datos de ORDER BY en una subconsulta

10

Estoy usando una aplicación (MapServer - http://mapserver.org/ ) que envuelve las instrucciones SQL, de modo que la instrucción ORDER BY está en la consulta interna. P.ej

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

La aplicación tiene muchos controladores de bases de datos diferentes. Principalmente uso el controlador MS SQL Server y SQL Server 2008. Esto arroja un error si se encuentra un ORDER BY en una subconsulta.

Desde MS Docs (aunque parece que es para SQL Server 2000, todavía parece aplicarse):

Cuando utiliza una cláusula ORDER BY en una vista, una función en línea, una tabla derivada o una subconsulta, no garantiza la salida ordenada. En cambio, la cláusula ORDER BY solo se usa para garantizar que el conjunto de resultados generado por el operador Top tenga una composición consistente. La cláusula ORDER BY solo garantiza un conjunto de resultados ordenado cuando se especifica en la instrucción SELECT más externa.

Sin embargo, el mismo tipo de consulta cuando se ejecuta en Postgres (9) y Oracle devuelven resultados, con el orden definido en la subconsulta. En Postgres, el plan de consulta muestra que los resultados están ordenados y las notas de la versión de Postgres incluyen el elemento que implica que se utilizan órdenes de subconsulta:

Evite ordenar cuando la subconsulta ORDER BY coincida con la consulta superior

http://en.wikipedia.org/wiki/Order_by dice:

Aunque algunos sistemas de bases de datos permiten la especificación de una cláusula ORDER BY en subselecciones o definiciones de vista, la presencia allí no tiene ningún efecto.

Sin embargo, desde mi propia comprobación de planes de consulta:

  • SQL Server 2008 no admite ORDER BY en una subconsulta
  • Postgres 9 admite ORDER BY en una subconsulta
  • Oracle 10g admite ORDER BY en una subconsulta

Entonces, mi pregunta, ¿hay algún enlace que pueda confirmar o negar oficialmente que Postgres y Oracle no permiten la clasificación en una subconsulta?

geographika
fuente
2
El hecho de que observe ciertos resultados no los garantiza. Si quieres consistencia, haz el pedido en el exterior. Período.
Aaron Bertrand
Idealmente, esto es lo que se implementará. Sin embargo, llegar a esta etapa implicará cambios en la lógica central y muchos controladores de bases de datos. Como este problema no se ha informado en muchos años, parece que algunos dbs implementan sistemáticamente ORDER BY en subconsultas. Sería bueno saber cuáles, si es posible.
geographika
2
@geographika Incluso si algunos DBMS lo hacen de manera consistente hasta ahora, no hay garantía de que continúen haciendo lo mismo en el futuro. Como ejemplo, las mejoras de MySQL del optimizador en 5.6 (y MariaDB 5.3) identificarían el ORDER BYen la subconsulta como redundante y no realizarían la clasificación innecesaria.
ypercubeᵀᴹ

Respuestas:

15

Tendrás que hacer que tu aplicación no ponga el ORDER BYinterior de la subconsulta (tal vez tenga la opción de no usar una subconsulta innecesaria en primer lugar). Como ya descubrió, esta sintaxis no es compatible con SQL Server sin ella TOP. Y con TOP, a menos que desee dejar algunas filas fuera, el uso TOP 100 PERCENTva a representar el ORDER BYoptimizado de todos modos.

Y en Oracle y PostGres, solo porque la sintaxis sea compatible , no significa que se obedezca. Y solo porque lo observe como obedecido en algún escenario, no significa que continuará siendo obedecido a medida que salgan nuevas versiones o con cambios sutiles en sus datos, estadísticas, la consulta o el entorno.

Puedo asegurarle que, sin duda , si desea una garantía sobre el pedido, debe colocar la ORDER BYconsulta más externa. Esta debería ser una doctrina que mantengas cerca sin importar qué plataforma estés usando.

Está solicitando un enlace que declara oficialmente que algo no es compatible. Esto es como buscar en el manual del propietario de su automóvil una declaración oficial de que su automóvil no puede volar.

Aaron Bertrand
fuente
Gracias. Creo que MSSQL tiene el enfoque correcto para arrojar un error. Tanto el soporte como la implementación de la ordenación en consultas internas, cuando va en contra de un principio básico de SQL, parece una receta para el desastre. No está seguro acerca de la analogía del coche, aunque - es necesario agregar en busca de ella en el manual mientras que el coche realmente está volando ..
geographika
-1

Admito que esto es de mala calidad, pero si estás en apuros, intenta devolver el número superior de filas en la subconsulta. Devolver el 100 por ciento superior no funciona, pero si desea pasar por el problema, puede consultar el número de filas y pasarlo a TOP como una variable. Probé esto en una base de datos establecida en el nivel de compatibilidad 80, así que creo que debería funcionar con SQL 2000.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl
DBNull
fuente
Intenté esto originalmente y parecía estar bien para pequeños conjuntos de datos. Sin embargo, cuando estaba obteniendo conjuntos de registros muy grandes, la ordenación se volvió aleatoria nuevamente en SQL Server 2008R2. Tal vez se relaciona con la memoria / tamaños de página?
geographika
Lo siento, no ayudó. Seleccionar el 100 por ciento superior también hizo que la clasificación volviera a ser aleatoria.
DBNull
Esto no funcionará si la consulta va paralela, especialmente si Nameno es única. Es posible que no continúe funcionando en serie si el optimizador elige un índice diferente, con un orden de columna de clave diferente.
Erik Darling