Hola fetre,
De entrada apostaria por que es más eficiente IN que EXISTS, pero... analicemoslo y a ver que sacamos.
La siguinte consulata muestra los datos de los empleados con uno o más hijos:
- Código: Seleccionar todo
select *
from EMPLEADOS
where ID_EMPLEADO in (select distinct ID_EMPLEADO
from PARENTESCO
where TIPO = 'H')
En esta consulta el motor SQL recorrera la tabla PARENTESCO una sola vez para establecer la lista de empleados a seleccionar. Posteriormente realizara busquedas, que no recorridos, sobre la lista de empleados obtenida para determinar si satisfacen la clausula IN. Realizará tantas busquedas como registros tiene la tabla EMPLEADOS. Cabe destacar que esta lista esta en RAM y no en disco, por lo que vamos a suponer que las busquedas no tienen apenas coste, o si quieres, este es despreciable.
Diremos pues que recorrerá la tabla PARENTESCO una vez y la EMPLEADOS tambien una vez.Apliquemos ahora EXISTS para obtener lo mismo:
- Código: Seleccionar todo
select *
from EMPLEADOS E
where exists (select 1
from PARENTESCO P
where P.ID_EMPLEADO = E.ID_EMPLEADO
and P.TIPO = 'H')
En esta caso el motor SQL realizará busquedas, que no recorridos, sobra la tabla PARENTESCO para determinar si satisface o no la clausula IN.
Vamos a suoner que no existen indices, entonces las busquedas pueden implicar recorrer la tabla PARENTESCO para aquellos empleados que no tiene hijos, la recorrerá y al no existir el empleado en cuestion en la tabla PARENTESCO se omitirá el registro que se esta evaluando, pero el recorrido ya lo ha echo, y esto ocurrira para todos los empleados que no tengan hijos. Obviamente en este caso ya se ve que no es eficiente.
Si existen indices, que es lo normal, con pocos accesos determinará si existe el empleado en cuestion en la tabla PARENTESCO, pero estas busquedas se realizan en disco, no en RAM, por lo que el coste ya no es despreciable.
Asi pues en este caso se recorrera una vez la tabla EMPLEADOS y se realizaran N busquedas sobre la tabla PARENTESCO, tantas como registros tenga la tabla EMPEADOS.La cuestión entonces es determinar que es más eficiente, si realizar busquedas sobre la tambla PARENTESCO para cada registro de la tabla EMPLEADO o bien recorrer una sola vez la tabla PARENTESCO.
Yo diría que depende, olvidemos por un momento la relación que existe entre las tablas de ejemplo y supongamos que hay pocos registros en la tabla EMPLEADOS y muchos en la tabla PARENTESCO, entonces es más eficiente exists, puesto que se realizaran pocas busquedas soble la tabla PARENTESCO y, presumo, que esto es más rapido que realizar un recorrido sobre la misma.
Si por el contrario hay muchos registros en la tabla EMPLEADOS y pocos en la tabla PARENTESCO, entonces es más eficiente recorrerla una sola vez que realizar muchas busquedas sobre ella. De hecho cuando una tabla tiene pocos registros los indices relentizan la operación, es más rápido para el motor SQL recorrerla y filtrar todos sus registros, que usar los indices en el plan de ejecución.
La conclusión pues, y no se en cuanto acertada, es que dependerá de cada caso, del número de registros de las tablas que interviene y de los indices que tengan las mismas.No veas que rollo te he soltado
![Muy Feliz :D](./images/smilies/icon_e_biggrin.gif)
perdona, y encima tampoco te he dado una respuesta concreta.
Lo bueno de todo esto es que si tomamos las tablas de ejemplo, quizás lo más eficiente sea lo siguiente:
- Código: Seleccionar todo
select distinct E.*
from EMPLEADOS E, PARENTESCO P
where E.ID_EMPLEADO = P.ID_EMPLEADO
and P.TIPO = 'H'
Normalmente las consultas costosas se optimizan cuando se detectan, siempre puedes probar las distintas opciones y escoger en función de la que tarda menos en ejecutarse.
Saludos.