Author Topic: pregunta retorica: pl/sql  (Read 5688 times)

0 Members and 1 Guest are viewing this topic.

ken2

  • Guest
pregunta retorica: pl/sql
« on: March 02, 2012, 10:47:54 am »
jummmm tengo una duda compañeros.

¿Qué es más rápido en ejecutarse? (tomando en cuenta que todas las columnas filtradas son indices)

1. Una consulta que devuelve los valores de una tabla de 4 millones de registros, filtrados por periodo que
tiene como una de sus columnas una función que va a buscar otro dato en una tabla de 1 millon de registros
filtrado por periodo y número de contrato...

Algo asi como

select numero_contrato, facturacion_anual (numero_contrato) from datos_usuarios_el_salvador where periodo = 2011;

oooooooooooooooooooooooooooooooooooooooo

2. La misma consulta, pero que esta construida con un join a la misma tabla.

select d.numero_contrato, f.fact_anual from datos_usuarios_el_salvador d, facturacion f
where periodo = 2011 and f.numero_contrato = d.numero_contrato and f.periodo = 2011 and d.periodo = 2011;

La función facturacion_anual hace exactamente lo mismo....

Mi duda es bien técnica, ¿Qué forma seria la más optima en Oracle 11g?


 :drinks:

Offline mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Posts: 5665
  • Starlet - 999cc
    • mxgxw
Re: pregunta retorica: pl/sql
« Reply #1 on: March 02, 2012, 11:16:04 am »
jummmm tengo una duda compañeros.

¿Qué es más rápido en ejecutarse? (tomando en cuenta que todas las columnas filtradas son indices)

1. Una consulta que devuelve los valores de una tabla de 4 millones de registros, filtrados por periodo que
tiene como una de sus columnas una función que va a buscar otro dato en una tabla de 1 millon de registros
filtrado por periodo y número de contrato...

Algo asi como

select numero_contrato, facturacion_anual (numero_contrato) from datos_usuarios_el_salvador where periodo = 2011;

oooooooooooooooooooooooooooooooooooooooo

2. La misma consulta, pero que esta construida con un join a la misma tabla.

select d.numero_contrato, f.fact_anual from datos_usuarios_el_salvador d, facturacion f
where periodo = 2011 and f.numero_contrato = d.numero_contrato and f.periodo = 2011 and d.periodo = 2011;

La función facturacion_anual hace exactamente lo mismo....

Mi duda es bien técnica, ¿Qué forma seria la más optima en Oracle 11g?


 :drinks:

No se como funcionará a detalle ORACLE, pero lo que te voy a poner es en base a la experiencia que he tendio en SQL SERVER.

El JOIN (sin filtro) intentará hacer el match de todos los registros de la tabla A, que coincidan con la TABLA B en las columnas especificadas. Esto generalmente TOMA MAS TIEMPO. que si uno filtra previamente la consulta y luego hace el join.

Es decir:

Code: [Select]
SELECT
  TableA.*,
  TableB.*
FROM TableA INNER JOIN TableB ON TableA.key1=TableB.key1 AND TableB.key2=TableB.key2
WHERE
  TableA.key1=<cond1> AND
  TableA.key2=<cond2>

Tarda más tiempo que:

Code: [Select]
SELECT
  TableA.*,
  TableB.*
FROM
  (
SELECT * FROM TableA WHERE TableA.key1=<cond1> AND TableA.key2=<cond2>
) AS TableA INNER JOIN
(
SELECT * FROM TableB WHERE TableB.key1=<cond1> AND TableB.key2=<cond2>
) AS TableB ON TableA.key1=TableB.key1 AND TableB.key2=TableB.key2

¿Por qué toma más tiempo? Pues porque en el primer caso intenta hacer el match de todos los registros entre TABLA A y TABLA B.

En el segundo caso primero se hace la subconsulta que selecciona únicamente los registros que coincidan en el filtro y luego hace el match únicamente con estos registros.

Se supone que hay gestores que optimizan la consulta y hacen el "pre-filtro" de las tablas a las cuales hacen join, pero eso depende de cada gestor. Yo prefiero hacerlo de esa manera porque fuerzo a que se haga el filtro antes de hacer el join.

Ahora considerá también que el pre-filtro es eficaz para tablas que vos sabes que no vas a seleccionar todos los elementos. Es decir que si para cada elemento de TablaA existe un elemento en TablaB, entonces el tiempo va a ser approx el mismo lo hagas como lo hagas.
« Last Edit: March 02, 2012, 11:18:46 am by mxgxw »


Offline iron_kong

  • MiembrosReales
  • *
  • Posts: 25
Re: pregunta retorica: pl/sql
« Reply #2 on: March 02, 2012, 11:17:23 am »
con lo poco que se de oracle... las dos formas son esquivalentes por lo que decis de la funcion  "facturacion_anual" ... ademas por al cantidad de registros que mencionas el query me imagino que es tardado

yo optaria por la segunda opcion, pero en ves de WHERE... sugeriria JOIN, Los JOIN son mas flexibles, y el resultado deberia ser el mismo en cuanto a
rendimiento.

las tablas  "datos_usuarios_el_salvador" y  "facturacion"   me imagino que se puede hacer el amarre con  "numero_contrato" y los periodos correspondientes  para cada tabla...

tenia un enlace donde se explica mejor, el por que es mejor el JOIN... pero no lo encuentro... sorry

 

ken2

  • Guest
Re: pregunta retorica: pl/sql
« Reply #3 on: March 02, 2012, 11:24:59 am »
Interesante detalle lo del join jummm y si m.g.w. ammmm pero pensalo bien...

si haces las consultas asi... realmente esta usando los indices??? porque primero filtras una tabla A,
despues filtras una tabla B entonces tenes dos resultados en MEMORIA... ammm y si fueran 3 millones...
sera viable comparar estas dos tablas temporales ???? mmmm más que todo porque aqui los
servidores no son tri-palomas jaja, ese es el problemita  x_x

http://es.wikipedia.org/wiki/Ret%C3%B3rica


Offline mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Posts: 5665
  • Starlet - 999cc
    • mxgxw
Re: pregunta retorica: pl/sql
« Reply #4 on: March 02, 2012, 11:30:12 am »
Interesante detalle lo del join jummm y si m.g.w. ammmm pero pensalo bien...

si haces las consultas asi... realmente esta usando los indices??? porque primero filtras una tabla A,
despues filtras una tabla B entonces tenes dos resultados en MEMORIA... ammm y si fueran 3 millones...
sera viable comparar estas dos tablas temporales ???? mmmm más que todo porque aqui los
servidores no son tri-palomas jaja, ese es el problemita  x_x

http://es.wikipedia.org/wiki/Ret%C3%B3rica


Si no tenes mucha memoria podrías hacerlo en dos pasos. El primer paso que te guarde los resultados del filtro en tablas  temporales y el segundo que haga el match y te devuelva el resultado. Creo que ORACLE te permite hacer tablas temporales que solo son accesibles desde el procedimiento que se está ejecutando.

Nosotros teníamos un problema similar pero para nuestro caso eran registros de "posición", tenemos una base de datos con un par de millones de puntos que representan "población". Una consulta geográfica es efectiva pero es bastante lenta, así que aplicabamos un pre-filtro por coordenadas y te lo digo una consulta que tardaba hasta 30 seg, con el pre-filtro se redujo a 1 o lo mucho 2 segundos.

Los join son muy útiles, pero al menos en mi experiencia personal cuando tenes muchos registros (como es tu caso) he notado que funcionan mejor cuando los trabajas con datos pre-filtrados.
« Last Edit: March 02, 2012, 11:34:17 am by mxgxw »


Offline Camus de Acuario

  • The Communiter-
  • *
  • Posts: 8455
  • Ōrora Ekusukyūshon!
Re: pregunta retorica: pl/sql
« Reply #5 on: March 02, 2012, 11:32:28 am »
Revisate el plan de ejecución de cada query y mira cual tiene más carga y si hay forma de bajarle, ya sea con uso de índices, hints, etc. Tratando de evitar un TABLE ACCESS FULL.

Hasta podrías realizar el query con un EXISTS y comparar las 3.

Acordate que para el plan de ejecución es mejor si ya le pones los datos de los filtros, para que te lo ejecute bien.

Por si no conoces la herramienta de plan de ejecución, te sirve como manera gráfica para ver exactamente eso, el plan de ejecución del query. Para saber en que tabla comienza, hacía cuales va, ver si ocupa algún indice o algo.

http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm

Yo lo ocupo tanto en Toad como en SQL Navigator, supongo que otros programas también lo trae.



Creo que ORACLE te permite hacer tablas temporales que solo son accesibles desde el procedimiento que se está ejecutando.
Así es, al momento de crearlas puedes hacer que sean: SESSION BASED o TRANSACTION BASED.
« Last Edit: March 02, 2012, 11:36:47 am by Camus de Acuario »

ken2

  • Guest
Re: pregunta retorica: pl/sql
« Reply #6 on: March 02, 2012, 11:36:21 am »
Si la conozco, es buenisima ! un regalo de los Dioses athenienses mmmm el asunto es que
las dos consultas tienen el mismo costo y cardinalidad, pero las dos son diferentes en los bytes usados
y pues ahi me entro la pregunta... por como los servidores de desarrollo solo nosotros los usamos, pero
los de producción los usan los usuarios de todas las agencias.... nyan !

Offline Francisco™

  • The Communiter-
  • *
  • Posts: 1373
  • Bitch you make me hurl...
Re: pregunta retorica: pl/sql
« Reply #7 on: March 02, 2012, 11:38:17 am »
[...]
La función facturacion_anual hace exactamente lo mismo....
[...]

hey una pregunta, decis que funcion hace exactamente lo mismo que el query del punto 2? si es diferente podrias poner exactamente que haces dentro de ella...

edit:
Si la conozco, es buenisima ! un regalo de los Dioses athenienses mmmm el asunto es que
las dos consultas tienen el mismo costo y cardinalidad, pero las dos son diferentes en los bytes usados
y pues ahi me entro la pregunta... por como los servidores de desarrollo solo nosotros los usamos, pero
los de producción los usan los usuarios de todas las agencias.... nyan !
bueno entonces si hacen lo mismo, me imagino que la que usa menos bytes es el query sin la funcion o no?

:offtopic:
Quote
En retórica, la interrogación retórica o pregunta retórica es, dentro de las figuras literarias, una de las figuras de diálogo. Se trata de una pregunta que se formula sin esperar respuesta. Puede presentarse bajo dos modalidades: la interrogatio, si la respuesta solo admite un sí o un no, y el quaesitum, si la respuesta tiene que ser más precisa.
http://es.wikipedia.org/wiki/Interrogaci%C3%B3n_ret%C3%B3rica
« Last Edit: March 02, 2012, 11:40:23 am by Francisco™ »

Offline tekun

  • -^- Elite Silver -^-
  • The Communiter-
  • *
  • Posts: 3221
  • Han convertido mi casa en cueva de mercaderes!!!!
    • www.tekun.es
Re: pregunta retorica: pl/sql
« Reply #8 on: March 06, 2012, 08:31:07 am »
LOS JOIN no sirven, bueno en cuanto a rendimiento se refieren, son mil veces mas performante los EXISTS o los IN / NOT IN....


en cuanto a tu pregunta inicial, obviamente se tardaran lo mismo, pero si la definición de la función no esta bien echa, usando la función se tardara más.
lo difícil lo hago rápido, con lo imposible, casi siempre me tardo un poquito