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

Tablas Grandes : 2 Consultas

Estas en el tema de Tablas Grandes : 2 Consultas en el foro de PostgreSQL en Foros del Web. Estimados amigos: Agradezco su recomendación en torno al siguiente problema : Cuando la Tabla en la que se almacenan unos datos, sobrepasa 1.5 Millones de ...
  #1 (permalink)  
Antiguo 06/03/2008, 14:34
 
Fecha de Ingreso: noviembre-2007
Mensajes: 13
Antigüedad: 16 años, 4 meses
Puntos: 1
Tablas Grandes : 2 Consultas

Estimados amigos:

Agradezco su recomendación en torno al siguiente problema :

Cuando la Tabla en la que se almacenan unos datos, sobrepasa 1.5 Millones de registros presenta los siguientes problemas, al tratar de visualizar los Datos por medio de un Refcursor :

a. Ni por el PgAdmin, ni desde la consola del Servidor, se abre el Refcursor. Si los
Datos son extraidos a traves de una función con salida SETOF, entonces si se
visualizan los datos. He reconfigurado los parametros max conection,shared
buffer, max_fsn_pages,max_fsn_relation, apliando sus capacidades, pero el
problema sigue igual.
En el intento de extracción de los datos, en ambos casos (PgAdmin y Consola
del Servidor) utilizo la forma normal, a traves de FETCH, indicando la referencia
que corresponde al Refcursor.

b. Las Tablas estan indexadas y definidas bajo la forma normal ("Indicevariable"
serial NOT NULL), sin embargo, he observado que en algunas tablas ese
inidice deja de ser consecutivo en alunos registros y se mantiene consecutivo
en otros, incluso en la misma Tabla.

Mil gracias anticipadas, por la recomendación que pudieren darme al respecto y
adicionalmente mil gracias al amigo Seyko, por su excelente recomendación en la
solución del Problema: ¿ Trigger o demonio? .

Saludos.

amilano.
  #2 (permalink)  
Antiguo 07/03/2008, 05:42
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

Exactamente para que necesitas el cursor?
Un cursor con 1,5 millones de registros es un gran cursor
Realmente necesitas un cursor con tantos registros?
  #3 (permalink)  
Antiguo 07/03/2008, 07:39
 
Fecha de Ingreso: noviembre-2007
Mensajes: 13
Antigüedad: 16 años, 4 meses
Puntos: 1
Re: Tablas Grandes : 2 Consultas

Seyko, buenos días :

Los datos almacenados en el refcursor, son tomados de muchas funciones que en la mayoría de los casos devuelven, a su vez, un SETOF. Dicho de otro modo, la función que genera el refcursor, llama a muchas funciones que devuelven un SETOF y lo convierte en refcursor.
Entonces el refcursor se utiliza para evitar crear un tipo de dato diferentes, para los resultados de cada función llamada por el refcursor. Los datos a los que se referencia con el refcursor, son enviados a una interfase WEB, que a través de una conexion con BD, llama a una unica función que genera los datos a visualizar en la interfase, por lo que de otro modo, tendría que hacerse la llamada a cientos de funciones diferentes, caso éste, en que igualmente deberian crearse cientos de tipos de datos diferentes.

Agradeciendo tus comentarios.

amilano.
  #4 (permalink)  
Antiguo 10/03/2008, 02:28
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

Vamos que si necesitas que el cursor sea tan grande!

Bien ahora cual es realmente el problema, que no te abre el cursor, que no puedes leerlo, ... ¿?¿?

Pon algo de ejemplo, si te da algun error, etc

A la espera
  #5 (permalink)  
Antiguo 10/03/2008, 10:09
 
Fecha de Ingreso: noviembre-2007
Mensajes: 13
Antigüedad: 16 años, 4 meses
Puntos: 1
Re: Tablas Grandes : 2 Consultas

Seyko, buenos días :

El problema es que no abre el cursor (por tanto no lo lee), sin arrojar ningun tipo de error. Debo abortar la ejecución porque se queda en un loop que sobrepasa los 2 millones de ms. El problema no sucede cuando se desea presentar los datos para una cantidad menor de registros, caso este en que la respuesta es inmediata y con lo cual se descarta la posibilidad de que el loop se produzca por una incorrección en el Procedimiento de Almacenado.

Segun tu experiencia: ¿ cual es el tamaño optimo o maximo ( en Mb o Nro de Registros) que puede manejar entonces un Refcursor y con cual dimencionamiento de memoria ?. Agradezco tambien una sugerencia, en relación al punto (b) del mensaje inicial, relativo a que variables definidas como indices, se incrementan de manera aleatoria (no consecutivamente), cuando la Tabla excede de 1.5 Millones de Registros.
Un último Punto: tratando de optimizar un poco el codigo, he sustituido una parte del procedimiento de almacenado, por codigos que incluyen el uso de vistas para la extracción de datos, lo cual ha mejorado enormemente los tiempos de respuesta.Sin embargo, ello no sucede siempre, sino tambien de manera aleatoria, es decir, en muchos casos hago directamente el SELECT a la función que genera la vista, y tambien se queda en un LOOP para generarla, aun cuando la función que genera tal vista no utiliza elementos generadores de loop (FOR, WHILE, por ejemplo), es decir, la vista en unos casos se genera y en otros no. En todo caso la vista la estoy creando con las estructuras indicadas por el Manual :
'CREATE OR REPLACE VIEW vista_xxxxmmm AS
SELECT DISTINCT yy.columna1, yy.columna2, yy.columna3,zz.columna1,zz.columna2
FROM Tabla1 yy, Tabla 2 mm,Tabla3 yy,Tabla4 qq
WHERE (mm.columna1= ''' || K || ''') AND (mm.columna2=yy.columna4) AND qq.columna1=yy.columna1 AND qq.columna6=yy.columna2 ....etc.etc
ORDER BY yy.columna3 ASC';

Siendo la variable K, en el ejemplo, un dato o parametro de entrada a la vista. Pareciera que antes de llamar a esta vista, debe borrarse la anterior, lo cual no he encontrado como se hace, aunque tampoco estoy seguro que sea la causa del problema ( el problema de la vista, no el del refcursor, que es otra cosa)

Gracias anticipadas, por todo cuanto esté a su alcance y al alcance de los demás amigos del Foro.

saludos

amilano.
  #6 (permalink)  
Antiguo 11/03/2008, 04:24
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

Buenas amilano,
a ver no hay un numero máximo para el refcursor, pero creo que el problema de manejar un cursor de 2millones de registros es que se carga en memoria y si no cabe en RAM empieza a paginar y de ahi que sea muy muy lento y mientras vayas recorriendo el cursor se hará cada vez más lento.
De ahi la pregunta de si de verdad necesitabas un cursor tan grande.

Cita:
b. Las Tablas estan indexadas y definidas bajo la forma normal ("Indicevariable"
serial NOT NULL), sin embargo, he observado que en algunas tablas ese
inidice deja de ser consecutivo en alunos registros y se mantiene consecutivo
en otros, incluso en la misma Tabla.
Estás confundiendo conceptos. Esa tabla tiene un campo serial, que te crea una secuencia para insertar por defecto en ese campo. Por tanto, si insertas el 1,2,3 luego borras el 3 y vuelves a insertar usa el 4. Es simplemente una secuencia, a base de borrados y actualizaciones quedan huecos intermedios, es normal y no afecta para nada.
El tema de los indices es otro cantar.

Sobre la vista: CREATE OR REPLACE, esto te borra la vista si ya existe.

Cita:
in embargo, ello no sucede siempre, sino tambien de manera aleatoria, es decir, en muchos casos hago directamente el SELECT a la función que genera la vista, y tambien se queda en un LOOP para generarla, aun cuando la función que genera tal vista no utiliza elementos generadores de loop (FOR, WHILE, por ejemplo), es decir, la vista en unos casos se genera y en otros no.
A que te refieres con que se queda en un LOOP????


Cita:
Los datos almacenados en el refcursor, son tomados de muchas funciones que en la mayoría de los casos devuelven, a su vez, un SETOF. Dicho de otro modo, la función que genera el refcursor, llama a muchas funciones que devuelven un SETOF y lo convierte en refcursor.
Entonces el refcursor se utiliza para evitar crear un tipo de dato diferentes, para los resultados de cada función llamada por el refcursor. Los datos a los que se referencia con el refcursor, son enviados a una interfase WEB, que a través de una conexion con BD, llama a una unica función que genera los datos a visualizar en la interfase, por lo que de otro modo, tendría que hacerse la llamada a cientos de funciones diferentes, caso éste, en que igualmente deberian crearse cientos de tipos de datos diferentes.
Uff mandas 2 millones de registros a una interfaze web?????
O buscas la manera de reducir drasticamente el número de registros del cursor o tendrás que buscar otra forma de unir el resultado de las funciones.
Una tabla temporal, vistas, ....

Mira yo he probado esto:
Código:
CREATE OR REPLACE FUNCTION millones() RETURNS boolean AS
$BODY$
DECLARE	
	registro record;
BEGIN
	
	EXECUTE 'create table millones(id serial primary key, valor integer)';
	insert into millones (valor) select n from generate_series(1,2000000) n;
	
	FOR registro IN select * from millones 
	LOOP
		RAISE NOTICE '%', registro.valor;
	END LOOP;

	return true;
EXCEPTION WHEN OTHERS THEN
	RAISE NOTICE 'ERROR: % --> %', SQLSTATE, SQLERRM;
	return false;
END;
$BODY$ LANGUAGE 'plpgsql';
Y tarda un rato, pero claro son solo 2 campos por registro.


Un saludo, a la espera
  #7 (permalink)  
Antiguo 11/03/2008, 19:17
 
Fecha de Ingreso: noviembre-2007
Mensajes: 13
Antigüedad: 16 años, 4 meses
Puntos: 1
Re: Tablas Grandes : 2 Consultas

Seyko, buenas tardes :

Agradezco inmensamente sus valiosas recomendaciones, por lo cual ya estoy tratando de implementar sus aportes en relación al problema. Aunque ahora tengo mayor claridad, en la necesidad de encontrar nuevas formas de unir el resultado de las funciones sql que permiten visualizar los datos de las tablas, continuo con una duda, en relación, no ya con el tamaño de las tablas, sino con la estructura o tipo de dato con que se visualiza la salida Vs el rendimiento o velocidad con que se forman tales tipos. Para ello, he realizado unas pruebas a partir de 101.570 registros, bien lejos de lo inicialmente planteado que eran 1.5 millones de registros, obteniendose lo siguiente :
a. Se dispone de una función SQL, cuyo tipo de dato de salida es un SETOF, que devuelve 12 Columnas, la cual a su vez llama a dos funciones que crean vistas :
a.1. La función que crea la Vista1, con 12 columnas, requiere de 48.38 sec, para formar la vista que contiene 10.157 Registros y devuelve ademas un Integer que indica el total de registros. ¿ Está este tiempo de respuesta, dentro de lo que puede aceptarse como normal?
a.2. La funcion que crea la Vista2, con 6 columnas, que recibe como parametro de entrada un Id, producido por cada registro de la Vista1 y para cada Id, devuelve una vista de 10 registros ( de allí la cantidad total de Registros del Setof : 10x10.157=101.570 registros). Esta vista se genera en muy pocos ms.
El tiempo total para generar el setof es de 10.121 sec, es decir, el setof se forma a una velocidad aproximada de 600 Reg/min, rendimiento este que me parece muy pobre, por lo que agradezco me idiques tu opinión al respecto. Ahora bien, dado que ese SETOF debe ser convertido en un Refcursor , a ser abierto directamente desde el PgAdmin o desde el Web, se requerirá entonces un minuto adicional, es decir, que solo podría visualizarse 600 Reg/2 min o 300 Reg/min.
El procedimiento que he seguido, como se indica, utiliza vistas, y tu propuesta utiliza una tabla temporal, pero en conclusión, considero que producen los mismos resultados.
Si en tu opinión, los rendimientos indicados, estan dentro de los valores normales (pues ya no me quedan muchas opciones para optimizar el codigo), entonces definitivamente, la cantidad de registros que se encapsulan en el refcursor no debería exceder de 300, si se desea que el tiempo maximo de respuesta sea de un min.
Debo admitir que tienes toda la razón en cuanto a mi confusión con los indices, sin embargo, el problema subsiste aún en tablas en las que no se ha realizado ningun DELETE.
Gracias anticipadas por tu atención y bienvenidas las opiniones de los demás amigos del Foro.
Saludos.
amilano
  #8 (permalink)  
Antiguo 12/03/2008, 04:08
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

Buenas
Cita:
Agradezco inmensamente sus valiosas recomendaciones, por lo cual ya estoy tratando de implementar sus aportes en relación al problema. Aunque ahora tengo mayor claridad, en la necesidad de encontrar nuevas formas de unir el resultado de las funciones sql que permiten visualizar los datos de las tablas, continuo con una duda, en relación, no ya con el tamaño de las tablas, sino con la estructura o tipo de dato con que se visualiza la salida Vs el rendimiento o velocidad con que se forman tales tipos. Para ello, he realizado unas pruebas a partir de 101.570 registros, bien lejos de lo inicialmente planteado que eran 1.5 millones de registros, obteniendose lo siguiente :
a. Se dispone de una función SQL, cuyo tipo de dato de salida es un SETOF, que devuelve 12 Columnas, la cual a su vez llama a dos funciones que crean vistas :
a.1. La función que crea la Vista1, con 12 columnas, requiere de 48.38 sec, para formar la vista que contiene 10.157 Registros y devuelve ademas un Integer que indica el total de registros. ¿ Está este tiempo de respuesta, dentro de lo que puede aceptarse como normal?
a.2. La funcion que crea la Vista2, con 6 columnas, que recibe como parametro de entrada un Id, producido por cada registro de la Vista1 y para cada Id, devuelve una vista de 10 registros ( de allí la cantidad total de Registros del Setof : 10x10.157=101.570 registros). Esta vista se genera en muy pocos ms.
El tiempo total para generar el setof es de 10.121 sec, es decir, el setof se forma a una velocidad aproximada de 600 Reg/min, rendimiento este que me parece muy pobre, por lo que agradezco me idiques tu opinión al respecto. Ahora bien, dado que ese SETOF debe ser convertido en un Refcursor , a ser abierto directamente desde el PgAdmin o desde el Web, se requerirá entonces un minuto adicional, es decir, que solo podría visualizarse 600 Reg/2 min o 300 Reg/min.
El procedimiento que he seguido, como se indica, utiliza vistas, y tu propuesta utiliza una tabla temporal, pero en conclusión, considero que producen los mismos resultados.
El rendimiento no se mide en tiempo, porque influyen muchos factores.
VACUUM y EXPLAIN ANALYZE te pueden ayudar a ver donde está el "problema".

Cita:
Si en tu opinión, los rendimientos indicados, estan dentro de los valores normales (pues ya no me quedan muchas opciones para optimizar el codigo), entonces definitivamente, la cantidad de registros que se encapsulan en el refcursor no debería exceder de 300, si se desea que el tiempo maximo de respuesta sea de un min.
Hombre, esto es muy muy relativo. Siempre se puede hacer algo más.
postgresql.conf es el archivo de configuración, donde tienes muchos parametros que puedes modificar para mejorar el rendimiento.

Cita:
Debo admitir que tienes toda la razón en cuanto a mi confusión con los indices, sin embargo, el problema subsiste aún en tablas en las que no se ha realizado ningun DELETE.
Te lo cuento con un ejemplo.
Código:
aemprende=# create table aaa (id serial primary key, nombre varchar not null);
NOTICE:  CREATE TABLE creará una secuencia implícita «aaa_id_seq» para la columna serial «aaa.id»
NOTICE:  CREATE TABLE / PRIMARY KEY creará el índice implícito «aaa_pkey» para la tabla «aaa»
CREATE TABLE
aemprende=# insert into aaa values (default, 'jose');
INSERT 0 1
aemprende=# insert into aaa values (default, null);
ERROR:  el valor null para la columna «nombre» viola la restricción not null
aemprende=# insert into aaa values (default, 'pepe');
INSERT 0 1
aemprende=# select * from aaa;
 id | nombre
----+--------
  1 | jose
  3 | pepe
(2 filas)
al fallar el insert, el valor de la secuencia ya se ha capturado, por ello queda el hueco, no es necesariamente por un delete.

Si ves que la cosa sigue mal y es critico lo podemos mirar con más calma por privado.

Un saludo
  #9 (permalink)  
Antiguo 12/03/2008, 04:09
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

por cierto que version utilizas?
  #10 (permalink)  
Antiguo 12/03/2008, 16:42
 
Fecha de Ingreso: noviembre-2007
Mensajes: 13
Antigüedad: 16 años, 4 meses
Puntos: 1
Re: Tablas Grandes : 2 Consultas

Buenas tardes Seyko :

La version que utilizo es la 8.2.
Una ultima consulta, para cerrar este caso:

He logrado construir una unica vista que contiene todos los datos, que segun mi mensaje anterior se construía con 2 vistas. La función que genera esa vista, devuelve además la cantidad de registros que contiene. A partir de esta nueva vista he construido una función cuyo tipo de dato es un refcursor y con lo cual eliminaría el paso de obtener primero un setof y convertirlo, posteriormente a refcursor. Esta solución parece mucho mejor que las anteriores, pero tengo los siguientes problemas, a partir del codigo siguiente (una parte) :


nroreg := (SELECT vistaversion_II(arreparam));--crea la vista y devuelve el Nro registos
vista := 'vista_version_II';--nombre de la vista creada

OPEN cursorSalida FOR EXECUTE 'SELECT
columna2,
((columna3)||'-'||(columna4)),
((columna5)||','||(columna6)||','||(columna7)||',' ||(columna8)),
to_char((columna9)*(columna10),'999G999G999G999G99 9G999G999G 999')

FROM

' || vista || ''

WHERE
fecha=dat--dat es uno de los parametros de entradas de esta funcion y fecha es una de las columnas de la vista

ORDER BY [columna10] DESC;

return cursorSalida ;


los problemas son los siguientes :
1.- Presenta el siguiente mensaje de error "ERROR: operator is not unique: "unknown" - "unknown"
Estado SQL:42725. El mensaje solo desaparece si se elimina el dato de salida ((columna3)||'-'||(columna4)), pero sin modificar ninguna columna de la vista
2. Cuando se elimina el dato de salida del punto anterior, entonces presenta mensaje"ERROR: column "fecha" does not exist, siendo que la vista efectivamente se crea con esta columna.

Muy probablemente el error esta en la construcción de este tipo de refcursor, a partir de una vista (es la primera vez que intento hacerlo), pero definitivamente no encuentro donde esta el Error.
Gracias por toda la ayuda brindada. Indiqueme, por favor la forma, de obtener su correo electronico o cualquier otro tipo de contacto, a efectos de NO sobrecargar el foro.

amilano.
  #11 (permalink)  
Antiguo 13/03/2008, 05:16
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Tablas Grandes : 2 Consultas

Cita:
Iniciado por amilano Ver Mensaje
Buenas tardes Seyko :

La version que utilizo es la 8.2.
Una ultima consulta, para cerrar este caso:

He logrado construir una unica vista que contiene todos los datos, que segun mi mensaje anterior se construía con 2 vistas. La función que genera esa vista, devuelve además la cantidad de registros que contiene. A partir de esta nueva vista he construido una función cuyo tipo de dato es un refcursor y con lo cual eliminaría el paso de obtener primero un setof y convertirlo, posteriormente a refcursor. Esta solución parece mucho mejor que las anteriores, pero tengo los siguientes problemas, a partir del codigo siguiente (una parte) :


nroreg := (SELECT vistaversion_II(arreparam));--crea la vista y devuelve el Nro registos
vista := 'vista_version_II';--nombre de la vista creada

OPEN cursorSalida FOR EXECUTE 'SELECT
columna2,
((columna3)||'-'||(columna4)),
((columna5)||','||(columna6)||','||(columna7)||',' ||(columna8)),
to_char((columna9)*(columna10),'999G999G999G999G99 9G999G999G 999')

FROM

' || vista || ''

WHERE
fecha=dat--dat es uno de los parametros de entradas de esta funcion y fecha es una de las columnas de la vista

ORDER BY [columna10] DESC;

return cursorSalida ;


los problemas son los siguientes :
1.- Presenta el siguiente mensaje de error "ERROR: operator is not unique: "unknown" - "unknown"
Estado SQL:42725. El mensaje solo desaparece si se elimina el dato de salida ((columna3)||'-'||(columna4)), pero sin modificar ninguna columna de la vista
2. Cuando se elimina el dato de salida del punto anterior, entonces presenta mensaje"ERROR: column "fecha" does not exist, siendo que la vista efectivamente se crea con esta columna.
Creo que el problema esta en las comillas '
prueba OPEN cursorSalida FOR SELECT ....

Opino que para estos temas es mejor que quede reflejado en el foro, para futuros visitantes.
Si necesitas algo concreto escribeme un privado y te doy mi email.

Salu2
  #12 (permalink)  
Antiguo 20/03/2008, 11:05
 
Fecha de Ingreso: abril-2007
Mensajes: 63
Antigüedad: 17 años
Puntos: 0
Re: Tablas Grandes : 2 Consultas

Ah. Saudos

que buen tema. y estoy seacuerdo seyko que deveria quedarse en el foro los respuestas para un lector pueda leer y aprender, y espero que no sea tan tarde esta opion, pero creo que el uso de cursores no es favorables cuando se utiliza muchos datos y mas cuando es un cursor para desplazammiento y es muy lento. espero estar en lo correcto y si no quiesiera saber SI ES BUENO O NO UTILIZAR UN CURSOR. Y CUAL SERIA LA OPCIONA UTILIZAR
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




La zona horaria es GMT -6. Ahora son las 04:11.