2010-01-25 13 views
6

que tienen una tabla de Oracle con el número de registros de 99896618.Oracle y paginación

necesito a buscar pequeña porción de datos (digamos 100 registros) para mostrar en una página web, (En el mundo web que llamarlo paginación). Actualmente estoy usando la siguiente consulta para lograr eso, sin embargo, los usuarios no están satisfechos con el rendimiento.

SELECT * FROM (select rownum rnum,f.* from findings f where rownum<90000100) 
        WHERE rnum > 90000000 

Actualmente tarda 1 min 22 segundos en obtener los resultados. ¿Hay alguna forma de hacerlo mejor? Definitivamente estoy abierto a cualquier tipo de sugerencia, incluida la modificación de la estructura de la tabla o como la adición de índices.

(Sólo para tu información, estoy usando ASP.NET como la tecnología web en el servidor y ADO.NET como capa de acceso de datos y presentación de Silverlight para el lado del cliente)

Respuesta

6

Su consulta deberá contar los primeros registros 90M para obtener el siguiente 100, por lo que apenas hay margen de mejora.

No veo una cláusula ORDER BY en su subconsulta, pero probablemente la tenga. En este caso, es posible que desee crear un índice en él.

Y una pregunta: ¿los usuarios realmente haga clic a través 900K páginas antes de quejarse de rendimiento?

Actualización:

Si necesita la última página, es necesario volver a escribir su columna ORDER BY en orden descendente:

SELECT * 
FROM (
     SELECT rownum rnum, f.* 
     FROM findings f 
     ORDER BY 
       record_ordering_column DESC 
     ) 
WHERE rnum > 900 
     AND rownum <= 100 

y crear un índice en record_ordering_column

en cuenta que yo mezcle rownum de las consultas anidadas para mejorar el rendimiento.

Lee este artículo en mi blog para más detalles:

+0

Hice fácilmente accesible el número de página creando una lista desplegable de números de página (solo una descripción simplificada, he creado un control personalizado a través del cual pueden acceder fácilmente a las últimas 1000 páginas). Puede ser que esta sea información útil, la mayoría de las veces (alrededor del 95% del tiempo) los usuarios están interesados ​​en los últimos (últimos) registros. – funwithcoding

1

Si usted está dispuesto a modificar la tabla Yo sugeriría que agrega una columna rownumber a la tabla (utilizando un desencadenador de inserción y una secuencia para establecerlo) y luego agrega un índice a esa columna.

+0

No hay índices agrupados o no agrupados en Oracle: simplemente se denominan índices. –

+0

'@OMG Ponies': sí, ¡pero hay clústeres indexados en' Oracle'! :) – Quassnoi

+0

@OMG Ponies: una clave principal es un índice agrupado en Oracle y ninguno de los principales índices de clave primaria no está agrupado. Debe estar hablando de la palabra clave 'no agrupada' * que, en mi opinión, no existe en Oracle. –

5

De uno de sus comentarios:

mayor parte del tiempo (alrededor del 95% de las veces) los usuarios están interesados ​​en los últimos (últimos) registros

En ese caso, ¿por qué no mostrar los registros en orden inverso, de modo que el 95% de las veces los usuarios están interesados ​​en la página 1 en lugar de la página 900000?

Si realmente quieren ver la "página 900,000", significa que están interesados ​​en los datos de hace mucho tiempo, por lo que les permite filtrar los datos por ej. rango de fechas. No se va a realizar una búsqueda en 100 millones de filas sin ningún tipo de filtrado.

0

lo que realmente necesita para obtener toda la fila de atrás?Como esto significa que no está usando ningún índice.

Si todavía necesita para obtener toda la fila. Utilice el siguiente patrón:

SELECT * FROM findings f1 WHERE f1.rowid IN 
    (SELECT rownum rnum, row_id 
     FROM (
      SELECT f.rowid row_id 
       FROM findings f 
      ORDER BY record_ordering_column 
      ) 
    WHERE rownum > 900 
    ) 
WHERE rnum <= 100; 

Ver

Nota: la cláusula adicional SELECT sutil, así como el uso de la consulta ROWID.

Si añade un índice en record_ordering_column, entonces el paganation se use el índice para obtener un conjunto de ROWIDs. A continuación, solo cargue los bloques que contienen las filas identificadas por sus ROWID.

Ésta será mejor que su consulta actual que será un escaneo completo de tabla.