Alguna vez me han llegado cuestiones en la que se me preguntaba qué es mejor, en términos de rendimiento de las bases de datos Oracle, si utilizar en las consultas PLSQL subqueries (subconsultas) o utilizar joins (es decir, listar todas las tablas en la clausula FROM y unirlas en el WHERE). Lo primero que hay que tener claro es que escribir una consulta PL/SQL utilizando subqueries o utilizando joins es semánticamente diferente; además, utilizar una u otra forma puede derivar en que ambas consultas devuelvan resultados diferentes y que no sean directamente intercambiables.
Lo que yo recomiendo para elegir entre un tipo de consulta u otro es, en general, hacer lo siguiente:
- Utilizar una subquery o subconsulta cuando no se necesita ninguna columna de la tabla que es referenciada en la subquery.
- Utilizar un join en caso de necesitar alguna de las columnas.
Para intentar dejar las cosas algo más claras os dejo el siguiente ejemplo:
SELECT * FROM pedidos WHERE tipo_pedido IN (SELECT tipo_pedido FROM tipo_pedidos); SELECT p.* FROM pedidos p, tipo pedidos t WHERE p.tipo_pedido = t.tipo_pedido;
Mi opinión es que es mejor utilizar el primer SELECT, pero única y exclusivamente por razones semánticas, ya que la primera consulta es más fácil de "leer" que la segunda. Mientras que el primer SELECT lo que nos dice es "estoy obteniendo todos los registros de la tabla pedidos tales que el campo pedidos.tipo_pedido esté en la tabla tipo_pedidos", la segunda consulta lo que nos dice es "estoy juntando la tabla pedidos con la tabla tipo_pedidos". No obstante, para el optimizador de la base de datos Oracle ambas consultas son idénticas y el rendimiento de ambas será el mismo.
Otro aspecto a recordar es que normalmente una subconsulta o subquery no puede reemplazarse por un join o viceversa, la razón es que a menudo los resultados que devolverán serán diferentes. Por ejemplo:
SQL> SELECT * 2 FROM tipo_pedidos 3 WHERE tipo_pedido IN 4 (SELECT tipo_pedido 5 FROM pedidos) 6 / ID TIPO_PEDIDO -- ----------- 1 Online 2 Tienda 2 rows selected. SQL> SELECT t.* 2 FROM pedidos p, tipo pedidos t 3 WHERE p.tipo_pedido = t.tipo_pedido 4 / ID TIPO_PEDIDO -- ----------- 1 Online 1 Online .............. 1 Online 2 Tienda .............. 2 Tienda 14321 rows selected.
En conclusión, el optimizador de la base de datos Oracle siempre sabrá que es lo que tiene que hacer, por lo que a la hora de construir una consulta PL/SQL y valorar si utilizar una subquery o un join, deberemos tener en cuenta que una y otra manera de construir una consulta no son, por lo general, intercambiables, y de ser posible elegir, deberemos escoger aquella que sea más sencilla de interpretar.
Artículos relacionados: El almacenamiento de subconsultas PLSQL.
3 comentarios:
Y no sería mejor usar un EXISTS?
SELECT *
FROM pedidos p
WHERE EXISTS
(SELECT 1
FROM tipo_pedidos t
WHERE p.tipo_pedido = t.tipo_pedido
AND ROWNUM < 0);
Lo he visto más que la "clausula" IN para mejorar la optimización.
Saludos!
Bitelmaniaco, por lo general sí pero no siempre. En este caso concreto el rendimiento será similar. Por cierto, imagino que cuando escribiste ROWNUM < 0 quisiste escribir ROWNUM < 2.
Normalmente yo uso antes un EXISTS que un IN por temas del Explain Plan, ya que teóricamente tiene un Coste menor.
El ROWNUM lo escribí al revés, quería haber dicho ROWNUM > 0. Así en cuanto encuentre el primero, que es de lo que se trata, "sale" de esa subquery.
Por cierto, enhorabuena por el blog. Me gusta bastante!
Publicar un comentario