Ver Mensaje Individual
  #3 (permalink)  
Antiguo 15/01/2008, 15:05
Avatar de matanga
matanga
 
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años, 1 mes
Puntos: 85
Re: Cómo hacer select con un limitador del número de resultados (¡rownum falla!)

Hola,

No es que el ROWNUM te devuelva las filas en el orden en que fueron insertadas, el tema es que, a diferencia de MS SQL Server, Oracle primero hace el ROWNUM y despues el ORDER BY, y es bastante logico, es decir, porque ordenar algo que se va a descartar.

Fijate en el siguiente ejemplo, tengo una tabla con las siguientes filas

Código:
SQL> select * from t1;

        ID NAME
---------- --------------------
         1 name 1
         2 name 2
         4 name 4
         6 name 6
         3 name 3
         5 name 5

6 rows selected.
Intento la consulta que parece no funcionar, un ROWNUM con un ORDER BY, donde uno esperaria que el resultado de IDs sea del 1 al 5.

Código:
SQL> select * from t1 where rownum < 5 order by 1;

        ID NAME
---------- --------------------
         1 name 1
         2 name 2
         4 name 4
         6 name 6
Lo que en realidad pasa se puede ver en el plan de ejecucion de la consulta, donde claramente hace el filtro ROWNUM antes que el ORDER BY.

Código:
SQL> set autot on;
SQL> select * from t1 where rownum < 5 order by 1;

        ID NAME
---------- --------------------
         1 name 1
         2 name 2
         4 name 4
         6 name 6


Execution Plan
----------------------------------------------------------
Plan hash value: 3366502262

----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     2 |    20 |     4  (25)| 00:00:01 |
|   1 |  SORT ORDER BY      |      |     2 |    20 |     4  (25)| 00:00:01 |
|*  2 |   COUNT STOPKEY     |      |       |       |            |          |
|   3 |    TABLE ACCESS FULL| T1   |     2 |    20 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter(ROWNUM<5)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
        542  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          4  rows processed
EDITADO

Cita:
Lo que no sé es si haciendo eso se ralentiza demasiado la búsqueda y hay métodos más rápidos.
No se relentiza, lo unico que haces con esto es invertir el orden del plan de ejecucion.


Saludos

Última edición por matanga; 15/01/2008 a las 16:18