Optimizar consultas con Select field,field From

693 views
Skip to first unread message

Mario Bucio

unread,
Jan 31, 2012, 10:33:08 AM1/31/12
to Comunidad de Visual Foxpro en Español
Mi aplicación va muy lenta con las consultas de Select... Into Cursor

Mi dudas son:

1.-¿ La estructura de mi sentencia Select es la adecuada ?

2.- ¿El cursor creado queda siempre en la memoria?

3.- ¿Como puedo optimizar la sentencia usada, para que vaya más
rápido?

Esta es la sentencia que uso:

Select
IdHuerta,Huerta,IdSagarpa,IdCartilla,IdProductor,Ubicacion,Superficie,CatHuertas.IdRuta;
From BsJlsv!CatHuertas Where Deleted()=.F. And
IdCartilla=lnIdCartilla;
Into Cursor MyHuerto


De antemano a los que me puedan orientar.

Saludos cordiales,
Atentamente
Mario Bucio

Yvan Carranza

unread,
Jan 31, 2012, 10:45:36 AM1/31/12
to publice...@googlegroups.com
Revisa tus indices.

Carlos Miguel FARIAS

unread,
Jan 31, 2012, 10:57:37 AM1/31/12
to publice...@googlegroups.com
Cambios en la sintaxis:
Select IdHuerta,Huerta,IdSagarpa,IdCartilla,IdProductor,Ubicacion,Superficie,CatHuertas.IdRuta;
    From BsJlsv!CatHuertas Where !Deleted() And IdCartilla=lnIdCartilla;
    Into Cursor MyHuerto

El cambio en el código es muy sutil, y no cree que mejore mucho eso la velocidad.

Si usas VFP 9, podes crear un indice binario por la condición deleted() del registro.
Además, deberías tener un indice específico sobre idCartilla.

Saludos: Miguel, La Pampa (RA)

Samuel SM-H

unread,
Jan 31, 2012, 11:37:28 AM1/31/12
to publice...@googlegroups.com
 Mauricio,
si estas trabajando con DBF's  y tu indice contiene el filtro !DELETED(); por recomendación es mejor que tengas un proceso de limpieza de registros deleteados  osea aplicarle  PACK.
Luego de eso prueba tus Selects para ver la mejora.

Saludos.

alberto mancuso

unread,
Jan 31, 2012, 12:19:03 PM1/31/12
to publice...@googlegroups.com
Yo lo que haria es crear un indice por el campo que usas en where , yo tenia ese problema con una consulta y la velocidad fue magnifica usando la tabla con el indice
te paso un ejemplo de como lo uso

SELECT pedidos00
SET ORDER TO 2   ///   aca selecciono el indice 
set century on
set date french
*cc=1
SELECT pedidos00.numorden as nro , pedidos00.nombre as cliente , pedidos00.fec_venta as fecha , pedidos00.importe as importe ,PEDIDOS00.NUMVEND,pedidos00.pendiente FROM pedidos00 ;
WHERE pedidos00.numclie = cc ORDER BY nro INTO CURSOR tabla1
thisform.grid1.RecordSource=""
THISFORM.Grid1.SetAll("dynamicbackcolor", ;
"IIF(tabla1.pendiente = .f.,RGB(255,255,255), RGB(255,0,0))", "Column")
SELECT TABLA1
GO BOTTOM
WITH thisform.grid1
.RecordSource = "tabla1"
.columncount=4

.column1.Width = 60
.column2.Width = 260
.column3.Width = 80
.column4.Width = 80
.COLUMN4.INPUTMASK="99999999.99"
 
 

ENDWITH 

thisform.grid1.refresh()
SELECT DETAPEDI00.CANTIDAD , DETAPEDI00.DESARTIC AS DETALLE , DETAPEDI00.P_LISTA , DETAPEDI00.IMPORTE FROM DETAPEDI00;
WHERE DETAPEDI00.NUMORDEN = TABLA1.NRO INTO CURSOR TABLA2
THISFORM.GRID2.RecordSource="TABLA2"
WITH thisform.grid2
.RecordSource = "tabla2"
.columncount=4

.column1.Width = 60
.column2.Width = 260
.column3.Width = 80
.column4.Width = 80
.COLUMN4.INPUTMASK="99999999.99"
 
 

ENDWITH 

thisform.grid1.setfocus

saludos


El 31 de enero de 2012 12:45, Yvan Carranza <yvan.c...@gmail.com> escribió:

Luis Maria Guayan

unread,
Jan 31, 2012, 12:34:09 PM1/31/12
to publice...@googlegroups.com
Para que la tengas optimización plena, deberias tener (en este caso específico) índices por: IdCartilla y Deleted()

Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

Mario Bucio

unread,
Feb 1, 2012, 6:22:44 PM2/1/12
to Comunidad de Visual Foxpro en Español
Gracias a todos por sus sugerencias.

El caso es que no me gusta trabajar con "indices" por las malas
experiencias en la corrupcion de los archivos de indices aun contando
con UPS.

De cualquier modo se agradecen todas las sugerencia.

El cursor generado queda en Memoria ? o se graba fisicamente en
(aunque sea temporalmente) en el disco duro. ?

Saludos cordiales,
Atentamente
Mario Bucio Espinosa

On 31 ene, 11:34, Luis Maria Guayan <luismar...@gmail.com> wrote:
> Para que la tengas optimización plena, deberias tener (en este caso específico)índices por: IdCartilla y Deleted()
>
> Luis María Guayán
> Tucumán, Argentina
> _________________________http://www.PortalFox.com

Luis Maria Guayan

unread,
Feb 1, 2012, 6:45:16 PM2/1/12
to publice...@googlegroups.com
Si trabajas tus tablas sin indices olvidate de rapidez en tus consultas.

Los cursores generados son tablas temporales. Lo puedes comprobar con ? DBF("MiCursor")


Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________


Walter R. Ojeda Valiente

unread,
Feb 1, 2012, 11:06:11 PM2/1/12
to publice...@googlegroups.com
En realidad, los índices no siempre aumentan la velocidad de las búsquedas y de las consultas, eso depende de la cantidad de filas de la tabla y del modo de acceso a ella y de la selectividad. Además, las inserciones, modificaciones y borrados son más lentos cuando hay un índice (o varios) en la tabla.

Ese es justamente uno de los puntos que trato en el borrador de un documento sobre diseño de bases de datos que estoy escribiendo en mis escasos minutos libres. Hay varios benchmarks para demostrar lo anterior.

Saludos.

Walter.




Date: Wed, 1 Feb 2012 20:45:16 -0300
From: luism...@gmail.com
To: publice...@googlegroups.com
Subject: Re: [vfp] Re: Optimizar consultas con Select field,field From

Carlos Miguel FARIAS

unread,
Feb 2, 2012, 7:08:16 AM2/2/12
to publice...@googlegroups.com
En la vieja escuela se sujerian 6 reglas para establecer como diseñar y optimizar todo el manejo de datos.
1) Volumen de Datos: Una vez definidos los datos a almacenar, Reducir al maximo el volumen que los mismos ocuparan en el medio de almacenamiento o que deberá ser transmitido, ya sea por normalización, si no y tan o mas importante por tipo de datos y dimensionamiento de los datos en aquellos sistemas que es posible. Por ejemplo usar enteros de tamaño apropiado, lo mismo para campos númericos, campos de texto, etc. Y al consultar los datos, solo transferir los datos realmente necesarios en cada momento. Por ejemplo evitar SELECT * FROM ...
En los SGBD que lo soportan, los campos varchar en lugar de los character, permiten reducir el volumen de datos transferido.

A partir de aqui, se aplican los criterios bajo la pauta de que las posibilidades que se tienen se vayan descartando las que no funcionan según cada criterio.
2) Frecuencia y Modo de Uso: Si la frecuencia de uso es baja, no me preocupo de los factores de optimización de la consulta, a medida que se incrementa la frecuencia de acceso, tendré que preocuparme de optimizar el acceso. Ejemplos: Con muy alta frecuencia de acceso, podría pensar en transferir ciertos archivos al equipo local, o almacenarlos en memoria del cliente, de manera de que no circulen por la red, o ciertos archivos usarlos con acceso directo (esto se puede hacer solo con nativas y pocos sgbd) usando go record en lugar de indices.
En cuanto al modo de uso, no es lo mismo acceso al azar, que acceso secuencial. El acceso al azar, es mejor acerlo a traves de claves primarias, y en el caso de join entre tablas, podría ser necesario un indice sobre la clave foranea pero solo del lado muchos. En los accesos secuenciales (listado de clientes) puede ser conveniente crear indices sobre por ejemplo como suena (soundex) que son cadenas de pocos bytes por lo tanto, con el mismo resultado, se obtiene un indice mas chico (y este indice se justifica si la frecuencia de uso de dicho listado es alta).

3) Datos Estáticos o Dinámicos: Si los datos son extremadamente estáticos, a veces, conviene (si el volumen lo permite) tenerlos codificados en "duro" dentro del codigo. En otros casos, podrian estar en archivos locales del equipo cliente o en formato comprimido, que se carga al arrancar la aplicacion. Además los datos en esto casos, ya pueden estar ordenados fisicamente en el orden de uso, lo que lo hace mas eficiente todavia.
A medida que los datos se hacen más dinámicos (o sea, se modifican mas frecuentemente), tendrá que analizarse por separado como influyen las altas, los cambios y las bajas. Todas tienen problematicas diferentes.
Las altas masivas, si hay muchos indices activos, son mortales para el desempeño. Por ejemplo en VFP, el uso de autoincrementales propios (VFP8 y 9) es por si mismo hasta una 35% más lento.
Por ejemplo el append blank en nativas, es muchismas veces mas lento que el inser into, razon? muy simple. un append blank (sin buffer), carga un registro en blanco, por lo que cada indice primero se actualiza con datos "en blanco" y luego cada indice se actualiza los respectivos valores.
Además el append blank, puede crear conflicto en entorno multiusuario si dos o + a la vez intentan un append blanck, el segundo le da clave duplicada en primarias y candidatas.
En el caso de los cambios, si los datos que se cambian no corresponden a columnas indexadas, no hay problema con la cantidad de indices, pero si se modifican columnas correspondientes a indices, agarrate Catalina.
En el caso de las bajas, dependera de si son nativas o no. En los sgbd, una baja es definitiva (delete incluye pack), en estos un borrado lógico (como el de los xbase), debe hacerse modificando una columna de estado. Si los registros deben eliminarse fisicamente, en fox ya sabemos de la necesidad de uso exclusivo de tablas y luego el pack, en los sgbd, conviene el borrado logico (marcado de registro) y luego, en horarios de poca carga, hacer eliminación fisica.
Los sgbd no tienen problemas con tablas exclusivas, pero pueden bloquear el sistema y siempre un borrado, afecta todos los indices de la tabla.

4) Este criterio corresponde a la estructura de datos a utilizar (una vez que desechamos todas las que no son aplicables por los criterios anteriores) y por logica, para acceso secuencial, si los datos necesarios ya estan ordenados mejor, en acceso al azar, si puedo acceso directo (por número de registro o acceso hash), si no, indices primarios, u otros indices, si hay disponibles. Siempre que se crean indices, que estos sean lo mas chicos posibles.
Por ejemplo, en fox, los indices sobre columnas numericas, no importa su tamaño, se crea como una clave numerica de 8 bytes binarios. Entonces, si mis valores de clave son mas chicos, conviene convertilos a texto binario (BINTOC y CTOBIN). Eso reduce el tamaño del indice, y por lo tanto, el acceso mejora.

5) Este criterio indica que si nos quedan 2 o más estructuras que no hayan sido descartadas por los criterios anteriores, tendremos que elegir la más rápida.

6) Por ultimo, si todavia queda mas de una estructura potable, aplicaremos el criterio de la mas facil de programar.

Algunos pueden plantear que estos criterios son "muy viejos", pero siempre por ahi se escucha que los sistemas están lentos, pasa de que cada vez se manejan mayor cantidad de datos que saturan la red (contables, financieros, imagenes de productos, datos dactilares, correo electronico, chat, señal de radio, fotos pornos , etc.)


Saludos: Miguel, La Pampa (RA)



360.gif
Reply all
Reply to author
Forward
0 new messages