database - soporta - porque se dañan las tablas en mysql
¿La forma más rápida de verificar si hay algunos registros en una tabla de base de datos? (6)
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.
Debido a que 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 usando Oracle 10.
#De acuerdo con Hibernate Tips & Tricks https://www.hibernate.org/118.html#A2
Sugiere escribir de esta manera:
Entero recuento = (Entero) session.createQuery ("select count (*) from ...."). UniqueResult ();
No sé cuál es la magia de uniqueResult () aquí? ¿Por qué lo hace rápido?
Compare con "seleccionar 1 de mytable donde parent_id = passingId y rowrum <2", ¿cuál es más eficiente?
Antes que nada, necesitas un índice en mytable.parent_id.
Eso debería hacer que su consulta sea lo suficientemente rápida, incluso para tablas grandes (a menos que también haya muchas filas con el mismo parent_id).
Si no, podrías escribir
select 1 from mytable where parent_id = :id and rownum < 2
que devolvería 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.
No hay 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 superiores. 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 es 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 debería ejecutar algo como:
select ''y''
from dual
where exists (select 1
from parent_able
where parent_key = :somevalue)
Para DB2, hay algo así como select * from mytable where parent_id = ? fetch first 1 row only
select * from mytable where parent_id = ? fetch first 1 row only
. Supongo que algo similar existe para el oráculo.
Una consulta EXISTS es la indicada si 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 el "resultado único" de Hibernate, todo lo que hace es devolver un solo objeto cuando solo hay un objeto que devolver, en lugar de un conjunto que contiene 1 objeto. Si se devuelven resultados múltiples, el método arroja una excepción.]
select count (*) debería ser increíblemente rápido si tienes un índice, y si no lo haces, permitir que la base de datos aborte después de la primera coincidencia no ayudará mucho.
Pero ya que preguntaste:
boolean exists = session.createQuery("select parent_id from Entity where parent_id=?")
.setParameter(...)
.setMaxResults(1)
.uniqueResult()
!= null;
(Algunos errores de sintaxis son de esperar, ya que no tengo un hibernate para probar en esta computadora)
Para Oracle, maxResults se traduce en rownum por hibernación.
En cuanto a lo que hace uniqueResult (), ¡lee 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 ().
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 ser útil cuando necesite verificar las estadísticas de los datos de la tabla, independientemente del tamaño de la tabla y cualquier problema de rendimiento.