2010-01-25 10 views
10

Tengo una gran mesa para trabajar. Quiero comprobar si hay algunos registros cuyo parent_id es igual a mi valor de aprobación. Actualmente, lo que implemento esto es mediante el uso de "select count (*) from mytable where parent_id =: id"; si el resultado> 0, significa que existen.¿La forma más rápida de verificar si hay algunos registros en una tabla de base de datos?

Como esta es una tabla muy grande, y no me importa cuál es exactamente el número de registros que existe, solo quiero saber si existe, por lo que creo que count (*) es un poco ineficiente.

¿Cómo implemento este requisito de la manera más rápida? Estoy utilizando Oracle 10.

#

Según hibernación Consejos & trucos https://www.hibernate.org/118.html#A2

Se sugiere escribir así:

Entero count = (entero) session.createQuery ("select count (*) desde ... "). uniqueResult();

No sé cuál es la magia de uniqueResult() aquí? ¿Por qué lo hace rápido?

Comparar con "seleccionar 1 de mytable donde parent_id = passingId y rowrum < 2", ¿cuál es más eficiente?

Respuesta

9

Un EXISTE consulta es la de ir porque si usted no está interesado en el número de registros:

select 'Y' from dual where exists (select 1 from mytable where parent_id = :id) 

Esto devolverá 'Y' si existe un registro y nada de lo contrario.

[En términos de su pregunta sobre "uniqueResult" de Hibernate - todo lo que hace es devolver un solo objeto cuando solo hay un objeto para devolver - en lugar de un conjunto que contiene 1 objeto. . Si hay varios resultados se devuelven al método lanza una excepción]

+0

Ni siquiera necesita consultar DUAL - 'seleccione 'Y' de mytable donde parent_id =: id AND ROWNUM = 1' da resultados idénticos. –

+0

Sí, simplemente no me gusta "ROWNUM = 1" - no se siente tan transparente como una consulta EXISTS. Solo yo. –

2

Antes que nada, necesita un índice en mytable.parent_id.

Eso debería hacer su consulta lo suficientemente rápida, incluso para tablas grandes (a menos que también haya muchas filas con el mismo parent_id).

Si no es así, se podría escribir

select 1 from mytable where parent_id = :id and rownum < 2 

que devolver una sola fila que contiene 1 o ninguna fila en absoluto. No necesita contar las filas, solo encuentra una y luego abandona. Pero este es un SQL específico de Oracle (debido a rownum), y debería preferir no hacerlo.

+0

+1 para la recomendación de índice –

+2

Me gustaría una consulta EXISTS creo - más transparente para el requisito: seleccione 1 de dual donde existe (seleccione 1 de mytable donde parent_id =: id) –

0

Para DB2 hay algo así como select * from mytable where parent_id = ? fetch first 1 row only. Supongo que algo similar existe para el oráculo.

+1

Todos los dialectos SQl difieren - no puede suponer que hay cosas similares, por ejemplo Oracle tiene rownum que no está en Sybase y creo que en DB2 – Mark

+2

, por lo que el concepto rownum es lo que yo llamaría "similar" porque cubre el mismo caso de uso, es decir, obtiene los n registros superiores (http: //www.petefreitag. com/item/59.cfm) – bertolami

+0

re: arriba n. Un problema con rownum es que se evalúa antes de que se realice cualquier clasificación, por lo que no es realmente "superior" n. – Thilo

4

No hay ninguna diferencia real entre:

select 'y' 
    from dual 
where exists (select 1 
       from child_table 
       where parent_key = :somevalue) 

y

select 'y' 
    from mytable 
where parent_key = :somevalue 
    and rownum = 1; 

... al menos en Oracle10gR2 y hacia arriba. Oracle es lo suficientemente inteligente en esa versión para realizar una operación RÁPIDA DOBLE donde pone a cero cualquier actividad real en su contra. La segunda consulta sería más fácil de transportar si eso fuera alguna vez una consideración.

El diferenciador de rendimiento real es si la columna parent_key está indexada o no. Si no es así, entonces usted debe ejecutar algo como:

select 'y' 
    from dual 
where exists (select 1 
       from parent_able 
       where parent_key = :somevalue) 
5

select count (*) debe ser lighteningly rápido si tiene un índice, y si no lo hace, lo que permite la base de datos para abortar después del primer partido ganado no ayuda mucho

Pero ya que lo preguntas:

boolean exists = session.createQuery("select parent_id from Entity where parent_id=?") 
         .setParameter(...) 
         .setMaxResults(1) 
         .uniqueResult() 
       != null; 

(Algunos errores de sintaxis que se esperaba, ya que yo no tengo una hibernación para probar en contra en este equipo)

Para Oracle, se traduce en maxResults rownum por hibernación.

En cuanto a lo que hace uniqueResult(), ¡lea su JavaDoc! Usar uniqueResult en lugar de list() no tiene impacto en el rendimiento; si recuerdo bien, la implementación de delegados uniqueResult para list().

+0

+1 para setMaxResults – Thilo

0

Esta consulta devolverá 1 si existe algún registro y 0 en caso contrario:

SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2); 

Podría ayudar cuando se necesita para comprobar las estadísticas de datos de la tabla, sin tener en cuenta el tamaño de la tabla y cualquier problema de rendimiento.

Cuestiones relacionadas