index en consultas mysql desde vfp?

663 views
Skip to first unread message

Saúl Piña

unread,
Sep 30, 2014, 10:49:55 AM9/30/14
to publice...@googlegroups.com
Saludos, he creado indices a mis tablas para los campos que utilizo para buscar y crear consultas sql, pero no sé como podría optimizar las consultas.  He cambiado las consultas solo por los campos que necesito, pero aun asi, me doy cuenta que recorre toda la tabla hasta encontrar el registro ingresado.  Mi tabla no pasa de 350,000 con 40 campos.

Este es un ejemplo:

SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista","Listado")
SELECT Listado
*BROWSE

LOCAL cdat
cdat=65786390

SELECT folio, ncompleto FROM Listado WHERE VAL(folio)=cdat INTO CURSOR Listado2 nofilter
    IF RECCOUNT()>0
    Thisform.text5.value=alltrim(ncompleto)
    endif


Pero con este código recorre toda la tabla, me gustaria algo similar a lo que se hace en vfp con tablas.dbf:
LOCAL cdat
cdat=65786390

Select Lista
set order to folio  <---Ordeno por el index "folio"
seek cdat
    If found()
    Thisform.text5.value=alltrim(ncompleto)
    endif

Es lo que más extraño de las DBF, Facil no?

Muchas gracias

Irwin Rodriguez

unread,
Sep 30, 2014, 11:21:45 AM9/30/14
to publice...@googlegroups.com
Hola Saúl,

Según veo solo necesitas un registro desde tu base de datos, el 65786390
para ser especificos.

Ahora veo que te estas trayendo todos los registros y los depositas en un temporal para luego buscar dicho registro desde el mismo temporal.

Si lo que necesitas es ese unico registro entonces estas tratando muy mal los recursos ya que estas trayendote 249 mil registros para nada.

Lo que debes hacer es crear un indice por el campo folio en la base de datos y en tu consulta solamente haz esto:


LOCAL cdat
cdat=65786390
SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista where folio=" +
cdat + " LIMIT 1","Listado")

Con eso te debería de ejecutar mucho más rápido.

Prueba y comentas.

Saludos!
--
Ing. Irwin Rodríguez
 
Consultor Informático
 
"Las ideas son fuerzas intangibles, pero tienen más poder que el cerebro físico de donde nacen. Tienen el poder de seguir viviendo, aún después de que el cerebro que las ha creado haya regresado al polvo"

NOTA: La información mostrada en este mensaje es de caracter Confidencial y está dirigida unicamente a los contactos señalados en el encabezado; si el lector de este correo no es el destinatario del mismo, se le notifica que cualquier copia o distribución queda totalmente prohibida. Si usted ha recibido este mensaje por error, por favor notifique inmediatamente al remitente por este mismo medio y bórrelo de su sistema.

Saúl Piña

unread,
Sep 30, 2014, 11:51:10 AM9/30/14
to publice...@googlegroups.com
Saludos irwin, me aparece un error:  operator and operant is not valid

Te adelanto que, folio es de tipo "decimal" en mysql y que thisform.text3.value es de tipo numerico en el campo, por lo tanto cdat es de tipo numérico.

Lo he intentado asi:

LOCAL cdat
cdat=thisform.text3.value  <-- aqui escribo el valor si eligo option 1
SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista where folio=" +
cdat + " LIMIT 1","Listado")

Antonio.xt

unread,
Sep 30, 2014, 11:58:05 AM9/30/14
to publice...@googlegroups.com

Saul, ese es el problema, si cdat es numerico no lo puedes concatenar a la instruccion select de esa manera, tienes que convertirlo a string para incluirlo en la sentencia SELECT.

O podrias usar la variable parametrizada, no uso MySQL y no se si funcione ahi, lo mas seguro es que si, ya que asi se utiliza en SQL y Firebird.

LOCAL cdat
cdat=65786390

SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista where folio=?
cdat LIMIT 1","Listado")

Irwin Rodriguez

unread,
Sep 30, 2014, 11:59:32 AM9/30/14
to publice...@googlegroups.com
Entiendo, ahora intenta entonces convirtiendo de numerico a string de la siguiente forma.

LOCAL cdat
cdat=
alltrim(str(thisform.text3.value))
SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista where folio=" +
cdat + " LIMIT 1","Listado")

Julián May

unread,
Sep 30, 2014, 12:00:14 PM9/30/14
to publice...@googlegroups.com
No utilizo MySql  pero en cualquier motor la lógica sería la misma.

Creas un indice sobre el campo que deseas que se haga la búsqueda.
En Sql son candidatos para indices las columnas sobre las cuales harás búsquedas.

Ya que los tengas definido ahora solo haces el query sobre el registro no hay necesidad de traer todos los registros y hacer una búsqueda sobre el cursor.

Solo necesitas harías SELECT Columna1, Columna2 FROM Tabla WHERE Columna3 = 'MiDato'
Y si esto lo realizas dentro de un procedimiento almacenado pues tendrías mejor velocidad ya que se ejecuta desde el servidor una de las recomendaciones en la administración de base de datos es que le dejes todas las tareas al servidor siempre y cuando las pueda haces. 

Saludos. 

Saúl Piña

unread,
Oct 1, 2014, 9:48:40 AM10/1/14
to publice...@googlegroups.com
Muchas gracias, a todos, Irwin funciona de maravilla, voy a revisar si existe para cambiar otrs consultas y adecuarlas al ejemplo que me enviaste.

Gracias Julia, voy a tomar en cuenta lo que comentas, pero no entendí esta frase:

"Y si esto lo realizas dentro de un procedimiento almacenado pues tendrías mejor velocidad"

Como saber si ya tengo procedimiento almacenado? o como se desarrolla, me interesa mucho lo de la velocidad en las consultas? 

Irwin Rodriguez

unread,
Oct 1, 2014, 10:05:42 AM10/1/14
to publice...@googlegroups.com
Saúl,

Eso quiere decir es que para agilizar tus consultas sería bueno tenerlas encapsuladas dentro de procedimientos o funciones almacenadas.

Los procedimientos almacenados no existen por si solos, tienes que crearlos según tu necesidad.

Por ejemplo para tu consulta podrías tener un procedure más o menos como este:
DELIMITER $$
USE `MiDataBase`$$
DROP PROCEDURE IF EXISTS `p_bucarregistro`$$
CREATE DEFINER=`root`@`%` PROCEDURE `p_bucarregistro`(IN p_folio int(20))
BEGIN
	/*Verifico si el código existe en base de datos*/
	SET @query = CONCAT("select folio, ncompleto FROM bd1.Lista where folio=", p_folio, " limit 1");
	PREPARE stmt1 FROM @query;
	EXECUTE stmt1;
END$$
DELIMITER ;

¿Cómo se ejecutan?

De la misma forma que ejecutas tu consulta desde VFP. Te devolverá el resultado dentro de tu cursor.

Espero te sirva de ayuda.

Saludos!

Saúl Piña

unread,
Oct 1, 2014, 10:21:22 AM10/1/14
to publice...@googlegroups.com
Saludos Irwin, para confirmar, el ejemplo que me envias, lo creo en la opcion "methods" del formulario?  otra cosa, si utilizo varias tablas para consultas, por ejemplo 4 tablas, debo crear un procedure por cada tabla?

muy agradecido...

Irwin Rodriguez

unread,
Oct 1, 2014, 10:41:23 AM10/1/14
to publice...@googlegroups.com
Todo gestor de bases de datos serio dispone del uso de procedimientos y funciones almacenadas, por lo tanto éstos deben crearse dentro de la base de datos.

Para tu caso deberás ingresar a la interfáz grafica (Workbench, QueryTools, HeidiSQL, etc) y ubicar en tu base de datos la seccion o carpeta de "Stored Procedures" o simplemente en el Query Editor colocas el script de tu SP y lo ejecutas.



si utilizo varias tablas para consultas, por ejemplo 4 tablas, debo crear un procedure por cada tabla?

Si las 4 tablas están dentro de una sola consulta entonces debes crear un solo procedure.

Puedes crear tantos procedures como necesites, la idea de esto es dejar todos los procesos grandes del lado del Servidor y no saturar el cliente ya que éste solo debe dedicarse a interactuar con los datos que retornan los SP.

Saludos!

INVERSIONES WIMARPER CA

unread,
Aug 1, 2020, 11:58:18 PM8/1/20
to Comunidad de Visual Foxpro en Español
Buenas noches, amigo Irwin, me llamo Richard Marrero soy Analista de Sistemas una consulta, como haz hecho con el ERROR de TABLA que da Visual Foxpro cuando se va la energía eléctrica. 


El martes, 30 de septiembre de 2014, 11:29:32 (UTC-4:30), Irwin Rodriguez escribió:
Entiendo, ahora intenta entonces convirtiendo de numerico a string de la siguiente forma.

LOCAL cdat
cdat=
alltrim(str(thisform.text3.value))
SQLEXEC(lhandle,"select folio, clave, ncompleto from bd1.lista where folio=" +
cdat + " LIMIT 1","Listado")

Luis suescún

unread,
Aug 2, 2020, 5:02:56 PM8/2/20
to publice...@googlegroups.com
utiliza el set tablevalidate creo que con 0, luego vas a modi stru le puedes agregar un campo, guardas, cierras y abres de nuevo la tabla, borras el campo adiciomado y vielves a guardar y ya deberias tener tu tabla disponible...

--
Visita el Blog de la Comunidad Visual FoxPro en Español: http://comunidadvfp.blogspot.com
---
Has recibido este mensaje porque estás suscrito al grupo "Comunidad de Visual Foxpro en Español" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a publicesvfoxp...@googlegroups.com.
Para ver esta conversación en el sitio web, visita https://groups.google.com/d/msgid/publicesvfoxpro/59adea63-73b3-4fed-a1f2-fefc93b222d9o%40googlegroups.com.

Luis suescún

unread,
Aug 2, 2020, 5:04:39 PM8/2/20
to publice...@googlegroups.com
y te sugiero abrir tu bd y trabajar con sqlcinnect, sqlexec.y no tener tablas abiertas 

El sáb., 1 ago. 2020 22:58, INVERSIONES WIMARPER CA <wima...@gmail.com> escribió:
--
Reply all
Reply to author
Forward
0 new messages