Re: Funciones en C mejorar performance

From: "jvenegasperu (dot)" <jvenegasperu(at)gmail(dot)com>
To: Ayuda <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Funciones en C mejorar performance
Date: 2013-05-25 06:20:50
Message-ID: CA+KjtGfR2jxSgDRKvxr8Hxu7OHjepTL4AFRx0pmJ5df=yp9-UQ@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Jaime, Alvaro nuevamente gracias por responder

revise mi codigo y algunas cosas las puse ya calculadas dentro de tablas
implica mucha redundancia pero la performance mejora increiblemente asi que
imagino que con triggers lograre que se mantenga la informacion
consistente, es decir en la consulta donde uso el azimuth obtengo el angulo
de una linea de una via y la comparo con el angulo de alguna linea de red
de agua si son lineas que tienen angulo parecido lo uso en el metrado de la
red por via, meti el resultado de las vias y redes en dos tablas y luego
corri la consulta sobre esas tablas de 90 seg paso a 3 a 5 segs con el
doble de datos mas que suficiente para mi con respecto a la consulta de
latitud y longitud tomando en cuenta el link que dejo Jaime la hice mas
sencilla como les copio el codigo abajo haber si se puede mejorar mas

y ahora tengo otra duda.

veran el caso es el siguiente: tengo poligonos que representan manzanas que
no tiene nombre, el nombre se obtiene de un campo en la tabla de lotes.
Hice la consulta para obtener el nombre de la manzana con la tabla lotes
pero una manzana puede tener 20 lotes otra 15 lotes y asi arme la consulta
y funciona el problema es que si tengo 100 manzanas y cada una tiene 20
lotes entonces con mi consulta se ejecutan 2000 updates lo cual funciona y
efectivamente coloca el nombre a la manzana sin embargo pienso habra alguna
forma de obtener solo un lote por cada manzana para de ahi sacar el nombre
aqui les pongo la consulta haber como se podria cambiar para que solo
salgan lo 100 registros con un lote por manzana que me sirva para esta
actualización. la consulta la pongo aqui:

update cat_manzana set nombre = substr(l.v_gral,0,10)
from cat_lote l,cat_manzana m, cat_sector
where st_contains(cat_sector.the_geom,cat_manzana.the_geom) and
st_contains(cat_manzana.the_geom,l.the_geom)
and l.v_gral ilike '%mz%' and cat_manzana.gid = m.gid and
cat_sector.id_sector = 10

Y aprovechando que Jaime me confirma que las consultas funcionarian mas
rapido en C podria alguien poner como seria el codigo de esta consulta en
una funcion en C enviando como parametro el id del sector.
tomando en cuenta lo que me indica Jaime que previamente esta consulta
tendria que mejorarse para que solo devuelva en este caso 100 registros
esto si que me ayudaria muchisimo es decir tengo muchos casos asi para
colocar nombres y la velocidad de procesamiento es una prioridad muy alta
ya que los recursos de hardware que tenemos es muy limitada y ahorrarle
aunque sea unos milisegundos de procesamiento al procesador vendria fabuloso

gracias nuevamente y espero sus comentarios copio aqui tambien la funcion
cambiada de la latitud y longitud haber si se puede mejorar mas trabajo con
postgres 9.1 y postgis 1.5

CREATE OR REPLACE FUNCTION geography()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
NEW.geo4326 := st_transform(NEW.geo,4326);
NEW.lat:= st_y(st_transform(NEW.geo,4326));
NEW.longi:= st_x(st_transform(NEW.geo,4326));
NEW.geoborde:= st_buffer(NEW.geo,1);

RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

CREATE TRIGGER geography
BEFORE INSERT OR UPDATE OF geo
ON d_bz
FOR EACH ROW
EXECUTE PROCEDURE geography();

El 17 de mayo de 2013 08:22, Jaime Casanova <jaime(at)2ndquadrant(dot)com>escribió:

> 2013/5/16 jvenegasperu . <jvenegasperu(at)gmail(dot)com>:
> > Hola Alvaro, Jaime gracias por responder.
> >
> > respecto a la función ST_aslatlontext ya revise y lamentablemente solo
> esta
> > disponible en postgis 2 y yo tengo 1.5 vere de migrar a postgis 2, las
> > consultas si estan usando los indices espaciales de hecho sin ellos ni
> > siquiera se podria ejecutar la consulta en mi pc jeje.
> >
>
> tienes razón, esa consulta esta disponible desde postgis 2.0 pero
> encontre una forma de determinar lo mismo en 1.5
> fijate si esto resulta más rápido que lo que tienes ahora o no.
>
>
> http://gis.stackexchange.com/questions/19099/how-to-extract-latitude-longitude-values-for-specific-points-from-a-shapefile
>
>
> > con respecto a que el trigger se ejecute en cuando haya modificado la
> > columna geometria las funciones se llaman con esto no sabia que podia
> poner
> > un trigger a ejecutar solo cuando cambia una columna espeifica al menos
> es
> > lo que te entendi o no es asi?
> >
> > CREATE TRIGGER vias_limitrofes
> > BEFORE UPDATE
> > ON op_sectores_abastecimiento
> > FOR EACH ROW
> > EXECUTE PROCEDURE vias_limitrofes();
> >
>
> asi es. pero no has dicho que versión de postgres tienes, si es 9.1 o
> superior tu CREATE TRIGGER quedaría así
>
> CREATE TRIGGER vias_limitrofes
> BEFORE UPDATE OF the_geom
> ON op_sectores_abastecimiento
> FOR EACH ROW
> EXECUTE PROCEDURE vias_limitrofes();
>
> este trigger no deberías ejecutarlo también en INSERT?
>
>
> >
> > las funciones de hecho funcionan bien pero cuando tengo un poligono que
> > tenga dentro por ejemplo unas 1000 manzanas para localizar sus calles o
> > ductos de redes de agua empiezan los problemas y he visto aplicaciones en
> > web que lo hacen muy rapido y queria saber si escribiendo las funciones
> en C
> > quizas la performance mejore un poco al tener la función dentro de una
> DLL
> > si es asi por favor me podrian ayudar con algun ejemplo de una función
> en C
> > que me devuelva los registros de una tabla recibiendo algun parametro
> para
> > un where es decir no quisiera que necesariamente me ayuden con estas
> > funciones pero al menos una pista por donde empezar.
> >
> > Apelo a su experiencia para saber si esto en C correria mas rapido para
> > aventurarme a tratar de escribir estas funciones en C que tengo varias
> como
> > esta consulta que es de las mas pesadas que estoy utilizando espero
> puedan
> > ayudarme gracias
> >
>
> las funciones en C son generalmente más rápidas. sin embargo considera
> que si el problema es la sentencia SQL, seguirá siendo un problema
> también en C, porque el código C tendrá que enviar a ejecutar las
> consultas.
>
>
> En realidad tienes que ejecutar la consulta de abajo así? eso es muy
> poco optimizable (si es que puede optimizarse algo). no podrías mejor
> calcular los datos del WHERE primero y luego armar la sentencia
> dinámicamente?
>
> > select distinct on (a.gid) c.rotulo,a.gid,a.diametro,a.longitud as
> st_length
> > from met_alcantarillado_jvenegas a,met_calle_jvenegas c
> > where st_intersects(st_buffer(c.st_intersection,15),a.st_intersection)
> >
> > AND
> > (
> > (CASE WHEN
> >
> (st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))
> > < 180
> > THEN
> > CASE
> > WHEN
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) > 180
> > THEN
> >
> >
> ABS((st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) - 180)
> > ELSE
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516))
> > END
> >
> > ELSE
> >
> > CASE WHEN
> >
> (st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))
> >> 180
> > THEN
> > CASE
> > WHEN
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) < 180
> > THEN
> >
> >
> ABS((st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) + 180)
> > ELSE
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516))
> > END
> >
> > ELSE
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > )
> > END
> > END)
> > >
> >
> ((st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))-
> > 10)
> >
> >
> > and
> > (CASE WHEN
> >
> (st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))
> > < 180
> > THEN
> > CASE
> > WHEN
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) > 180
> > THEN
> >
> >
> ABS((st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) - 180)
> > ELSE
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516))
> > END
> >
> > ELSE
> >
> > CASE WHEN
> >
> (st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))
> >> 180
> > THEN
> > CASE
> > WHEN
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) < 180
> > THEN
> >
> >
> ABS((st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > ) + 180)
> > ELSE
> >
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516))
> > END
> >
> > ELSE
> >
> (st_azimuth(st_startpoint(a.st_intersection),st_endpoint(a.st_intersection))*(180/3.141516)
> > )
> > END
> > END) <
> >
> ((st_azimuth(st_startpoint(c.st_intersection),st_endpoint(c.st_intersection))*(180/3.141516))
> > + 10)
> > )
> >
> > order by a.gid,rotulo
> >
> >
>
> --
> Jaime Casanova www.2ndQuadrant.com
> Professional PostgreSQL: Soporte 24x7 y capacitación
> Phone: +593 4 5107566 Cell: +593 987171157
>

--
José Mercedes Venegas Acevedo
cel: Mov. 949808846

mails: jvenegasperu(at)php(dot)net
jvenegasperu(at)gmail(dot)com

PHP Spanish Docs translator member.
http://www.php.net/manual/es/index.php

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Miguel Beltran R. 2013-05-27 00:21:40 Re: Imagen de Base de Datos
Previous Message Lazaro Ruben Garcia Martinez 2013-05-24 14:05:13 Re: insertar valores en otra tabla cierta condicion.