Sobre la UNION en postgre!!!!

From: Rodolfo Vegas <vegasster(at)gmail(dot)com>
To: Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, pgsql-es-ayuda(at)postgresql(dot)org
Subject: Sobre la UNION en postgre!!!!
Date: 2009-05-13 14:37:46
Message-ID: 3e6a6f890905130737g16a0060ay2b8291ad8afcedb@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola de nuevo, como les habia dicho antes estaba implementando las
operaciones conjuntistas difuzas de las cuales el INTERSECT y el EXCEPT
estan ya hechas con éxito despues de tanto trabajo, ahora bien en la UNION
es que me ha costado más y les voy a decir la razón: La UNION difuza se
procede de la siguiente manera, tengo varios select's si eso select's son
difuzos cada uno de ellos trae un grado de membresía que ya es calculado,
ahora bien cuando se va a ejecutar la union, es la misma metodologia que la
union booleana, los comunes y no comunes en las tuplas sin repetir, y por
ejemplo si hay tuplas iguales se coloca la que tenga mayor grado de
membresía.

Ahora bien estoy estancado es en el caso de colocar el mayor grado de
membresái, porque? la union es distinta a la interseccion y except, ellos se
diferencia es que en la union el va a guardar desde el primer momento en que
se invoca la operacion las tuplas en la tabla resultante que se muestra por
pantalla y en el caso de que las tuplas sean iguales no se procede en
almacenarla porque se supone que ya esta guardada, por el contrario el
INTERSECT/EXCEPT ella guarda en la tabla resultante cuando encuentre tuplas
iguales asi que yo puedo modificar las tuplas que corresponda y ese cambio
se va a ver reflejado en el resultado, en la UNION no porque como el siempre
va a estar almacenando no tengo la oportunidad de cambiar lo del grado de
membresia.

Primero para ejecutar la union el invoca el execunique en el
nodeUnique.c (executor), al momento de pasar las tuplas en la tabla
resultante el invoca el ExecCopySlot y este a su vez llama al ExecStoreTuple

00401 {
00402 /*
00403 * sanity checks
00404 */

00405 Assert
<http://doxygen.postgresql.org/postgres_8h.html#706ac5b1a53bd04067f81924b92cb9f6>(tuple
!= NULL <http://doxygen.postgresql.org/c_8h.html#070d2ce7b6bb7e5c05602aa8c308d0c4>);

00406 Assert
<http://doxygen.postgresql.org/postgres_8h.html#706ac5b1a53bd04067f81924b92cb9f6>(slot
!= NULL <http://doxygen.postgresql.org/c_8h.html#070d2ce7b6bb7e5c05602aa8c308d0c4>);

00407 Assert
<http://doxygen.postgresql.org/postgres_8h.html#706ac5b1a53bd04067f81924b92cb9f6>(slot->tts_tupleDescriptor
<http://doxygen.postgresql.org/structTupleTableSlot.html#05ecbc8985e2aa98150efc96b6f43957>
!= NULL <http://doxygen.postgresql.org/c_8h.html#070d2ce7b6bb7e5c05602aa8c308d0c4>);

00408 /* passing shouldFree=true for a tuple on a disk page is not sane */
00409 Assert
<http://doxygen.postgresql.org/postgres_8h.html#706ac5b1a53bd04067f81924b92cb9f6>(BufferIsValid
<http://doxygen.postgresql.org/bufmgr_8h.html#b3e277e4bb71ca3f6768b72905321a26>(buffer)
? (!shouldFree) : true);

00410
00411 /*
00412 * Free any old physical tuple belonging to the slot.
00413 */

00414 if (slot->tts_shouldFree
<http://doxygen.postgresql.org/structTupleTableSlot.html#b1022e87bb8bf083b72f108959e87d65>)
00415 heap_freetuple
<http://doxygen.postgresql.org/heaptuple_8c.html#eb68a841af3401253a82a482bd259ecb>(slot->tts_tuple
<http://doxygen.postgresql.org/structTupleTableSlot.html#b9fc63474afc6eee52a06fcf29327c0d>);

00416 if (slot->tts_shouldFreeMin
<http://doxygen.postgresql.org/structTupleTableSlot.html#bf7e154658b2be2eaa414c44bc487cae>)
00417 heap_free_minimal_tuple
<http://doxygen.postgresql.org/heaptuple_8c.html#78d96975eb119a2ee1963ee9aa77bc58>(slot->tts_mintuple
<http://doxygen.postgresql.org/structTupleTableSlot.html#4facd3a81d2e4787021d25a536c21dd0>);

00418
00419 /*
00420 * Store the new tuple into the specified slot.
00421 */

00422 slot->tts_isempty
<http://doxygen.postgresql.org/structTupleTableSlot.html#b77ca0f307a440a5c80a19e267a0b846>
= false;
00423 slot->tts_shouldFree
<http://doxygen.postgresql.org/structTupleTableSlot.html#b1022e87bb8bf083b72f108959e87d65>
= shouldFree;

00424 slot->tts_shouldFreeMin
<http://doxygen.postgresql.org/structTupleTableSlot.html#bf7e154658b2be2eaa414c44bc487cae>
= false;
00425 slot->tts_tuple
<http://doxygen.postgresql.org/structTupleTableSlot.html#b9fc63474afc6eee52a06fcf29327c0d>
= tuple;

00426 slot->tts_mintuple
<http://doxygen.postgresql.org/structTupleTableSlot.html#4facd3a81d2e4787021d25a536c21dd0>
= NULL <http://doxygen.postgresql.org/c_8h.html#070d2ce7b6bb7e5c05602aa8c308d0c4>;

00427
00428 /* Mark extracted state invalid */
00429 slot->tts_nvalid
<http://doxygen.postgresql.org/structTupleTableSlot.html#7e582edf9c7e53c85ce7429eb170b57f>
= 0;

00430
00431 /*
00432 * If tuple is on a disk page, keep the page pinned as long
as we hold a

00433 * pointer into it. We assume the caller already has such a pin.
00434 *
00435 * This is coded to optimize the case where the slot previously held a

00436 * tuple on the same disk page: in that case releasing and
re-acquiring
00437 * the pin is a waste of cycles. This is a common situation during

00438 * seqscans, so it's worth troubling over.
00439 */
00440 if (slot->tts_buffer
<http://doxygen.postgresql.org/structTupleTableSlot.html#e5ec2377ede086dd340e9a2adf250c8b>
!= buffer)

00441 {
00442 if (BufferIsValid
<http://doxygen.postgresql.org/bufmgr_8h.html#b3e277e4bb71ca3f6768b72905321a26>(slot->tts_buffer
<http://doxygen.postgresql.org/structTupleTableSlot.html#e5ec2377ede086dd340e9a2adf250c8b>))

00443 ReleaseBuffer
<http://doxygen.postgresql.org/bufmgr_8c.html#9bc03ec5d254ee2f9fe05aa3536bb037>(slot->tts_buffer
<http://doxygen.postgresql.org/structTupleTableSlot.html#e5ec2377ede086dd340e9a2adf250c8b>);

00444 slot->tts_buffer
<http://doxygen.postgresql.org/structTupleTableSlot.html#e5ec2377ede086dd340e9a2adf250c8b>
= buffer;
00445 if (BufferIsValid
<http://doxygen.postgresql.org/bufmgr_8h.html#b3e277e4bb71ca3f6768b72905321a26>(buffer))

00446 IncrBufferRefCount
<http://doxygen.postgresql.org/bufmgr_8c.html#098140e762fc3118a109db6755a4a665>(buffer);
00447 }
00448

00449 return slot;
00450 }

y es en la línea 00425 que almacena dicha tupla en una estructura llamada
HeapTuple, entonces que es lo que estaba pensando yo, que al momento de la
ejecución de la UNION cuando encuentre que las tuplas que esta estudiando
son iguales recorrer todo el HeapTuple como si fuese una matriz, donde las
filas serían cada registro y las columnas el nombre de cada tupla tal cual
como muestra postre el resultado por pantalla, no es optimo porque sería un
recorrido secuencial y esa estructura de datos puede ser enorme por la
cantidad de registros pero es la unica solución que veo, recorrer todo el
HeapTuple y comparar con la tupla que se esta estudiando en la union para
determinar cual es el que tiene mayor grado de membresía si el que esta
dentro del HeapTuple o el que se esta procesando y asi lograr la
modificación, ahora la pregunta es se puede hacer ese recorrido en el
HeapTuple ó existe otra manera más facil y que consuma menos tiempo????????

--
Saludos,
Atentamente,
Lic. Rodolfo José Vegas Gómez.
Valencia - Venezuela

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Rafael Martinez 2009-05-13 15:02:33 Re: backups incrementales
Previous Message Edwin Quijada 2009-05-13 14:11:33 RE: backups incrementales