Para verificar la existencia de un registro es mucho mejor usar una función ad-hoc
existe, que verifique la existencia en vez de contar la cantidad de registros con un select count y preguntar si la cantidad de registros es mayor que cero. Esto es más dramático cuando usamos un where por un campo con valor no único o una clausula like. Por ejemplo, si deseamos saber si existe un registro con tipo de objeto = 'SYNONYM' , una alternativa (generalmente usada) es hacer:
SELECT COUNT (*)
FROM objetos
WHERE object_type = 'SYNONYM';
Una mejor alternativa es hacer una función:
FUNCTION existe (
p_object_type IN objetos.object_type%TYPE
)
RETURN BOOLEAN IS
CURSOR c_existe IS
SELECT 'x'
FROM objetos
WHERE object_type = p_object_type;
v_dummy VARCHAR2 (1);
v_existe BOOLEAN;
BEGIN
OPEN c_existe;
FETCH c_existe
INTO v_dummy;
v_existe := c_existe%FOUND;
CLOSE c_existe;
RETURN v_existe;
END existe;
El primer caso recorre todos los registros, en el segundo caso, solo llega al primer registro y retorna la existencia. Si creamos un bloque anónimo con llamadas iterativas a estas dos instrucciones, tenemos que el tiempo de ejecución es mucho menor para el código ad-hoc
eEvalua_Count_vs_Existencia.sql
La salida de este script es:
Select vía Count:Tiempo en segundos:TF-TI:147 segundos.
Función existe:Tiempo en segundos:TF-TI:2 segundos.
Por lo tanto, el tiempo de respuesta y el uso de recursos son mucho mejores en el segundo caso. Además, la función de existencia es fácil de implementar programáticamente usando el diccionario de la base de datos.
Una alternativa es usar un stop key en el select count(*), con esto, los resultados entre el count y existe se aproximan:
ResponderEliminarSELECT COUNT (*)
into v_count
FROM objetos
WHERE object_type = p_object_type
and rownum < 2;
hago un select simple y capturo la excepcion :)
ResponderEliminarEs otra alternativa, pero es más código y mas puntos de salida, en general, mientras más simple, mejor. Además de que esto solo sirve si estas pensando en PL/SQL, pero no puedes usarlo como parte de una subquery a no ser que sea una función como la mostrada al principio.
ResponderEliminarObservación: Para este efecto, el stop key funciona bien en oracle 10g o superior, en 9i está implementado, pero el costo es el mismo, asi que en ese caso recomiendo usar la función ad-hoc.
Te escribo desde el trabajo.
ResponderEliminarEstaba buscando una manera óptima para comprobar igualdades entre dos tablas.
Me viene ni que pintado.
Gracias!
Una alternativa es utilizar las operaciones de conjunto MINUS o INTERSECT:
ResponderEliminar(SELECT 1 id, 'R1' texto
FROM DUAL
UNION ALL
SELECT 2 id, 'R2' texto
FROM DUAL)
MINUS
SELECT 1 id, 'R1' texto
FROM DUAL;
(SELECT 1 id, 'R1' texto
FROM DUAL
UNION ALL
SELECT 2 id, 'R2' texto
FROM DUAL)
INTERSECT
SELECT 1 id, 'R1' texto
FROM DUAL;