Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Oracle »

Duda sobre rendimiento en selects con JOIN, ON y WHERE

Estas en el tema de Duda sobre rendimiento en selects con JOIN, ON y WHERE en el foro de Oracle en Foros del Web. Hola, ante una select típica del tipo: select a from t1 join t2 on t1.b=t2.b and t1.b='x' ¿Qué es mejor? ¿Que la búsqueda por uno ...
  #1 (permalink)  
Antiguo 28/01/2008, 11:25
 
Fecha de Ingreso: abril-2007
Mensajes: 160
Antigüedad: 17 años, 7 meses
Puntos: 1
Duda sobre rendimiento en selects con JOIN, ON y WHERE

Hola,

ante una select típica del tipo:

select a from t1
join t2 on t1.b=t2.b
and t1.b='x'

¿Qué es mejor? ¿Que la búsqueda por uno o varios valores en concreto vaya en el "ON", o en el WHERE (dejando así el ON sólo para uniones de campos entre tablas)? ¿O da lo mismo?

La sentencia de arriba utiliza sólo "ON". La equivalente, utilizando "WHERE", sería:

select a from t1
join t2 on t1.b=t2.b
where t1.b='x'
  #2 (permalink)  
Antiguo 28/01/2008, 11:37
 
Fecha de Ingreso: abril-2007
Mensajes: 160
Antigüedad: 17 años, 7 meses
Puntos: 1
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

En particular cabría preguntarse si los índices siguen funcionando igual de un modo o de otro.

Por ejemplo, supongamos que tenemos un índice en la tabla t1, basado en dos campos, a y b. Y ahora supongamos que queremos mostrar los datos de la tabla t1, que cumplan que 'a' sea un literal que le pasemos (por ejemplo 'xxx'), y 'b' tenga el mismo valor que otro campo equivalente que tengamos en otra tabla, que además cumpla en un tercer campo otra condición.

Tendríamos:

select a, b from t1 join t2
on t1.b=t2.b
and t1.a='xxx' and t2.c='un valor'

La duda sería entonces saber si el índice funciona, y si también funciona, y es más o menos eficiente, sacando la última línea del ON y poniéndola en un WHERE.
  #3 (permalink)  
Antiguo 28/01/2008, 11:49
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

Hola,

Es solo una cuestion de sintaxis, de todos modos si tienes dudas sobre como se accede a las tablas y a traves de que indices, utiliza el plan de ejecucion.

Código:
SQL> explain plan for select * from dual;

Explicado.

SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------

Plan hash value: 272002086

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     2 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

8 filas seleccionadas.
Saludos
  #4 (permalink)  
Antiguo 28/01/2008, 11:55
 
Fecha de Ingreso: abril-2007
Mensajes: 160
Antigüedad: 17 años, 7 meses
Puntos: 1
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

¡Ok, gracias!
  #5 (permalink)  
Antiguo 30/01/2008, 20:41
Avatar de Linterns
Colaborador
 
Fecha de Ingreso: diciembre-2001
Mensajes: 2.799
Antigüedad: 22 años, 11 meses
Puntos: 11
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

Los join en Oracle son ocupados para emular; tu sintaxis real en Oracle sería

Código PHP:
 select a 
from t1
t2
Where t1
.b=t2.b
and  t1.b='x' 
Prueba y veras que con millones de registros es mucho más eficiente pues es la sintaxis nativa de oracle en lugar de los Join; ahora si solo estas ocupando unos cuantos registros no veras una gran diferencia
__________________
Bien se puede recibir una puñalada sin adulación,
pero rara vez se recibe una adulación sin puñalada
** ***
  #6 (permalink)  
Antiguo 30/01/2008, 23:39
Avatar de kikolice  
Fecha de Ingreso: marzo-2004
Mensajes: 1.510
Antigüedad: 20 años, 8 meses
Puntos: 7
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

"Los join en Oracle son ocupados para emular;"

recuerdo haber leido un articulo que mencionaba que esta sintaxis era para seguir algun estandar (no recuerdo cual)
__________________
Blogzote.com :-) Mi blog
  #7 (permalink)  
Antiguo 30/01/2008, 23:44
Avatar de kikolice  
Fecha de Ingreso: marzo-2004
Mensajes: 1.510
Antigüedad: 20 años, 8 meses
Puntos: 7
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

ya decia yo que lo habia visto

http://www.orape.net/article71.html
__________________
Blogzote.com :-) Mi blog
  #8 (permalink)  
Antiguo 31/01/2008, 05:01
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Duda sobre rendimiento en selects con JOIN, ON y WHERE

Hola,

Este es un caso de prueba que creo podran reproducir sin problemas.

Código:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
Tengo dos tablas con una cantidad interesante de registros

Código:
SQL> select count(*) from t1;

  COUNT(*)
----------
   7989248

1 fila seleccionada.

Transcurrido: 00:00:03.87
SQL> select count(*) from t2;

  COUNT(*)
----------
   7994247

1 fila seleccionada.

Transcurrido: 00:00:03.54
Plan de ejecucion del primer JOIN

Código:
SQL> explain plan for
  2  select *
  3  from
  4  t1, t2
  5  where t1.object_name = t2.object_name
  6  and t1.object_name = 'T1';

Explicado.

Transcurrido: 00:00:00.01
SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------

Plan hash value: 2109126321

--------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|*  1 |  HASH JOIN                   |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1          |  1390 |   116K|  1263   (1)| 00:00:16 |
|*  3 |    INDEX RANGE SCAN          | IND_T1_NAME |  1390 |       |     8   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| T2          |  1467 |   123K|  1316   (1)| 00:00:16 |
|*  5 |    INDEX RANGE SCAN          | IND_T2_NAME |  1467 |       |     8   (0)| 00:00:01 |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."OBJECT_NAME"="T2"."OBJECT_NAME")
   3 - access("T1"."OBJECT_NAME"='T1')
   5 - access("T2"."OBJECT_NAME"='T1')

19 filas seleccionadas.

Transcurrido: 00:00:00.07
Plan de ejecucion del segundo JOIN

Código:
SQL> explain plan for
  2  select *
  3  from
  4  t1
  5  join t2 on t1.object_name = t2.object_name
  6  where t1.object_name = 'T1';

Explicado.

Transcurrido: 00:00:00.01
SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------

Plan hash value: 2109126321

--------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|*  1 |  HASH JOIN                   |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1          |  1390 |   116K|  1263   (1)| 00:00:16 |
|*  3 |    INDEX RANGE SCAN          | IND_T1_NAME |  1390 |       |     8   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| T2          |  1467 |   123K|  1316   (1)| 00:00:16 |
|*  5 |    INDEX RANGE SCAN          | IND_T2_NAME |  1467 |       |     8   (0)| 00:00:01 |

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."OBJECT_NAME"="T2"."OBJECT_NAME")
   3 - access("T1"."OBJECT_NAME"='T1')
   5 - access("T2"."OBJECT_NAME"='T1')

19 filas seleccionadas.

Transcurrido: 00:00:00.09
Plan de ejecucion del tercer JOIN

Código:
SQL> explain plan for
  2  select *
  3  from
  4  t1
  5  join t2 on t1.object_name = t2.object_name
  6  and t1.object_name = 'T1';

Explicado.

Transcurrido: 00:00:00.01
SQL> select * from table (dbms_xplan.display);

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------

Plan hash value: 2109126321

--------------------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|*  1 |  HASH JOIN                   |             |  2040K|   334M|  2597   (1)| 00:00:32 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1          |  1390 |   116K|  1263   (1)| 00:00:16 |
|*  3 |    INDEX RANGE SCAN          | IND_T1_NAME |  1390 |       |     8   (0)| 00:00:01 |
|   4 |   TABLE ACCESS BY INDEX ROWID| T2          |  1467 |   123K|  1316   (1)| 00:00:16 |
|*  5 |    INDEX RANGE SCAN          | IND_T2_NAME |  1467 |       |     8   (0)| 00:00:01 |

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------

--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."OBJECT_NAME"="T2"."OBJECT_NAME")
   3 - access("T1"."OBJECT_NAME"='T1')
   5 - access("T2"."OBJECT_NAME"='T1')

19 filas seleccionadas.

Transcurrido: 00:00:00.07
Presten especial atencion al valor de Plan hash value en cada uno de los planes de ejecucion. Los tres son iguales.

Ahora, segun la documentacion, la definicion de PLAN_HASH_VALUE es

Numerical representation of the SQL plan for the cursor. Comparing one PLAN_HASH_VALUE to another easily identifies whether or not two plans are the same (rather than comparing the two plans line by line).

Representación numérica del plan SQL del cursor. Comparando un PLAN_HASH_VALUE a otro identifica facilmente si dos planes son los mismos (en lugar de comparar los dos planes línea por línea)

En conclusion, es solo una cuestion de sintaxis, no tiene impacto en la consulta.

Saludos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 3 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 16:57.