2010-09-21 19 views
8

Quizás alguien me explique esto, pero cuando consulta una tabla de datos de Oracle, donde existen múltiples registros para una clave (digamos una ID de cliente), el registro que aparece primero para ese cliente puede variar si no hay una instrucción implícita de "orden por" que impone el orden, por ejemplo, un campo alternativo, como un tipo de transacción. Por lo tanto, ejecutar la misma consulta en la misma tabla podría generar un orden de registro diferente al de hace 10 minutos.Oracle SQL devuelve las filas de forma arbitraria cuando no se utiliza ninguna cláusula "order by"

Por ejemplo, una carrera podría Rendimiento:

Cust_ID, TRANSACTION_TYPE
123 A
123 B

A menos que una "orden por TRANSACTION_TYPE" cláusula se utiliza, Oracle podría arbitrariamente devolver el siguiente resultado la siguiente tiempo de la consulta se ejecuta:

Cust_ID, TRANSACTION_TYPE
123 B
123 A

Supongo que tenía la impresión de que había una ordenación predeterminada de las filas en Oracle que (tal vez) reflejaba el orden físico en el medio del disco. En otras palabras, un orden arbitrario que es inmutable y que garantizaría el mismo resultado cuando se vuelva a ejecutar una consulta.

¿Tiene esto que ver con el optimizador y cómo decide dónde recuperar más eficientemente los datos?

Por supuesto, la mejor práctica desde el punto de vista de la programación es forzar cualquier ordenamiento que se requiera, estaba un poco inquieto por este comportamiento.

+0

No sé por qué, pero esta es una observación muy divertida y especialmente la parte "desconcertante" de la misma. :) –

+0

No estás * forzando * ordenar, estás * escogiendo * it. – egrunin

Respuesta

8

No hay pedidos predeterminados, nunca. Si no especifica ORDER BY, puede obtener el mismo resultado las primeras 10000 veces, luego puede cambiar.

Tenga en cuenta que esto también es cierto incluso con ORDER BY para valores iguales. Por ejemplo:

Col1 Col2 
1 1 
2 1 
3 2 
4 2 

Si utiliza ORDER BY Col2, que todavía no saben si la fila 1 o 2 vendrán en primer lugar.

22

El orden de las filas devuelto a la aplicación desde una declaración SELECT es COMPLETAMENTE ARBITRARIO a menos que se especifique lo contrario. Si desea, necesita o espera que las filas vuelvan en cierto orden, es responsabilidad del usuario especificar tal orden.

(Advertencia:. Algunas versiones de Oracle sería implícitamente ordenar los datos en orden ascendente si se utilizan ciertas operaciones, tales como DISTINCT, UNION, MINUS, INTERSECT, o GROUP BY Sin embargo, como Oracle ha implementado hash de la clasificación, la naturaleza de la especie de los datos puede variar , y muchos SQL que dependen de esa función se rompieron.)

+6

+1 (o más exactamente, muchos * SQL confiando en esa característica * estaban expuestos como si siempre se hubieran roto *) –

+1

Casi me gustaría que a veces se requiriera la cláusula ORGANIZACIÓN, por lo que la gente se daría cuenta de que por defecto en Oracle, las tablas son organizado. –

+1

+1 - pero esto requeriría que las personas que han usado Oracle durante años (incluido) tengan que entender lo que significa la cláusula ORGANIZACIÓN de CREATE TABLE (y gracias, su comentario me impulsó a leer esto). –

5

La respuesta simple es que el estándar SQL dice que no hay un orden predeterminado para las consultas que no tienen una instrucción ORDER BY, por lo que nunca debe asumir una.

La verdadera razón probablemente estaría relacionada con los valores hash asignados a cada fila a medida que se extrae en el conjunto de registros. No hay ninguna razón para suponer un hash consistente.

6

Simplemente imagina las filas en una mesa como pelotas en una canasta. ¿Las bolas tienen un pedido?

No creo que haya ningún DBMS que garantice una orden si no se especifica ORDER BY.

Algunos pueden devolver las filas en el orden en que se insertaron, pero eso es un efecto secundario de la implementación.

Algunos planes de ejecución pueden provocar que se ordene el conjunto de resultados incluso sin ORDEN POR, pero de nuevo se trata de un efecto secundario de implementación en el que no debe confiar.

6

Si una cláusula ORDER BY no está presente, la base de datos (no solo Oracle, cualquier base de datos relacional) puede devolver filas en el orden en que las encuentre. Esto variará según el plan de consulta elegido por el optimizador.

Si el orden en el que se devuelven las filas debe tener en cuenta una cláusula ORDER BY. A veces puede tener suerte y las filas volverán en el orden en que desea que estén, incluso sin una ORDEN POR, pero no hay garantía de que A) tenga suerte en otras consultas, y B) el orden en que las filas se devuelven mañana será el mismo que el pedido en el que se devuelven hoy.

Además, las actualizaciones del producto de la base de datos pueden cambiar el comportamiento de las consultas. Tuvimos que esforzarnos un poco cuando realizamos una actualización importante de la versión el año pasado cuando descubrimos que Oracle 10 devolvía los resultados de GROUP BY en un orden diferente al de Oracle 9. Motivo: sin cláusula ORDER BY.

PEDIR POR: cuando el orden de los datos devueltos realmente importa.

+0

Wow, agrupar por no implica automáticamente el orden por. Gracias, tendré que recordar eso. Esta es otra instancia donde SAS SQL (llamado proc sql) difiere de Oracle SQL. Proc SQL en realidad ignoraría un orden por ser superfluo cuando una cláusula group by está presente. – jgunnink

2

si no utiliza ORDER BY, la orden es arbitraria; sin embargo, depende de almacenamiento físico y aspectos de memoria. por lo tanto, si repite la misma consulta cientos de veces en 10 minutos, obtendrá casi el mismo pedido cada vez, porque probablemente nada cambie.

cosas que podrían cambiar el "orden noorder" son:

  • el plan de ejecución - Si se cambia (se ha señalado que los )
  • inserciones y eliminaciones en las tablas implicadas en la consulta.
  • otras cosas como la presencia en la memoria de las filas. (Querys otros en otras tablas que podrían influir)
+0

Tienes razón, en su mayor parte nada cambiará. Me di cuenta de que en una consulta que devuelve un millón de filas, un par de miles podría ser diferente entre ejecuciones sucesivas. Mi compañero de trabajo, que es más experto en Oracle, me ha explicado que incluso si la ejecución del código y las tablas a las que se hace referencia son estáticas, los resultados podrían basarse en una serie de factores de tiempo de ejecución, algunos de los cuales ha mencionado. En realidad, me da una nueva apreciación de lo que Oracle está haciendo entre bastidores para maximizar la velocidad de recuperación. – jgunnink

0

Cuando usted consigue en la recuperación de datos en paralelo de E/S no es posible obtener diferentes secuencias en diferentes se ejecuta, incluso sin cambios en los datos almacenados?

Es decir, en un entorno de multiprocesamiento, el orden de finalización de los subprocesos paralelos no está definido y puede variar con lo que esté sucediendo en el mismo procesador compartido.

+0

No creo que haya nada que sugiera que la recuperación paralela de datos esté involucrada aquí. –

0

Como soy nuevo en el motor de base de datos Oracle, noté este comportamiento en mis declaraciones SELECT que no tienen ORDER BY.

He estado usando Microsoft SQL Server desde hace años. SQL Server Engine siempre recuperará los datos ordenados por el "Índice agrupado" de la tabla, que básicamente es el Índice de clave principal. SQL Server siempre insertará nuevos datos en un orden secuencial basado en el índice agrupado.

Por lo tanto, cuando realiza una selección en una tabla sin ordenar en SQL Server, siempre recuperará los datos ordenados por valor de clave principal.

ORDER BY puede causar una sobrecarga de rendimiento grave, es por eso que no desea utilizarlo a menos que no esté satisfecho con el orden de resultados inconsistentes.

Terminé con la conclusión de que en TODAS mis consultas de Oracle debo usar ORDER BY o terminaré con un orden imprevisto que afectará en gran medida mis informes de usuario final.

Cuestiones relacionadas