Page 1 of 2

ADS -> Optimizacion de consultas SQL

Posted: Fri Apr 28, 2006 2:57 pm
by Carles
Hola,

El siguiente codigo es ejecutado con FWH y funciona perfecto, pero si ejecuto una query con ARC32 ( Tools->Native SQL) el resultado es muchiiisimo mas rapido. Mi Pregunta es: Se puede optimizar la ejecucion de las funciones de SQL en ADS ?

Code: Select all

#include "ads.ch"
#include "fivewin.ch"	  

*--------------
FUNCTION main()
*--------------
    LOCAL cServer  := "\\BSD001\Test"
    LOCAL consulta := "Select * from Test where age > 90"
    LOCAL cTxt     := ''

    RddRegister("ADS",1)
    RddSetDefault("ADS")
    AdsSetServerType ( 2 )
    SET FILETYPE TO CDX


    AdsConnect( cServer , 2 )

    IF ! ADSCreateSQLStatement("SQLarea",2)  // 2 == ADS_CDX
       MsgAlert( "ADSCreateSQLStatement('SQLarea',2)" )
       RETU .F.
    ENDIF

    IF ADSExecuteSQLDirect( consulta )

       FOR nI := 1 TO 20

           cTxt += sqlarea->first + ' ' + sqlarea->last + ' ' + sqlarea->street + ' ' + str( sqlarea->age ) + CRLF
                   sqlarea->( DbSkip() )

       NEXT

       msgInfo( cTxt )

    ENDIF

    AdsDisconnect(AdsGetConnectionHandle())

    sqlarea -> ( DBCLOSEAREA() )

RETU NIL
Muchas gracias
Carlos.

Posted: Fri Apr 28, 2006 4:40 pm
by dbzap
El server que tu indicas en una carpeta de tablas DBF ?

Posted: Sun Apr 30, 2006 7:58 am
by Carles
Hola,

No entiendo tu pregunta. Se pretende trabajar contra servidor, no en modo local.

Saludos.
C.

Posted: Sun Apr 30, 2006 6:19 pm
by dbzap
no importa que sea un server ADS, la pregunta es si las tablas son archivos DBF o si es un server SQL, por ejemplo Microsoft SQL Server.
Eso.

Posted: Mon May 01, 2006 1:49 am
by wmormar
dbzap wrote:no importa que sea un server ADS, la pregunta es si las tablas son archivos DBF o si es un server SQL, por ejemplo Microsoft SQL Server.
Eso.
Si es Advantage, son base de datos DBF, advantage te da la ventaja SQL.

Posted: Tue May 02, 2006 6:38 am
by Carles
Hola,

No me explicado bien. Voy a intentarlo de nuevo :roll:

Quiero saber si contra un server ADS, y usando las funciones propias de ADS, como ADSExecuteSqlDirect(), se puede alcanzar la velocidad de ejecucion del ACE32 cuando se realizan las querys.

A modo de ejemplo, el test de arriba se me ejecuta en aproximadamente 6 segundos con la base test.dbf y 100000 registros, mientras que con Ace32 esta 0.7 seg. Partiendo de la base, que Ace32 no utiliza ni ODBC ni otros componentes de acceso a datos, (q yo sepa), me gustaria saber la diferencia.

No lo he probado via ODBC, pero la idea es usar solo las funciones ACE.

Gracias por vuestro soporte.

Posted: Tue May 02, 2006 12:10 pm
by Marcelo Via Giglio
Hola,

probaste con utilizar otro formato para el resultado

ADSCreateSQLStatement("SQLarea",n) 1,2,3

seria interesante ver como cambia esto, por otra parte el tiempo que das, lo 6 segundos es tomando en cuenta el tiempo de conexion previa a la consulta o solo la consulta

saludos

Marcelo

Posted: Tue May 02, 2006 12:20 pm
by Carles
Hola Marcelo,

1.- El 2º parametro es el tipo de tabla, siendo 2 == DBF_CDX (eso creo, ahora me haces dudar)

2.- El tiempo aprox. lo calculo sencillamente

Code: Select all

nInicio := Seconds()
ADSExecuteSQLDirect( consulta )
MsgInfo( Seconds() - nInicio )
No se si la gente esta usando esta funcion contra servidor que va de maravilla, pero es q jode ver como en el ARC32 vuela, al lado de la tuya. Pensaba que ARC32 usaba las mismas funciones del ACE.

Gracias por tu ayuda.

Posted: Tue May 02, 2006 3:22 pm
by Marcelo Via Giglio
Carles wrote:Hola Marcelo,

1.- El 2º parametro es el tipo de tabla, siendo 2 == DBF_CDX (eso creo, ahora me haces dudar)
Era para saber si afectava en que formato recibes el resultado, pueda que alli esta algo de la respuesta
No se si la gente esta usando esta funcion contra servidor que va de maravilla, pero es q jode ver como en el ARC32 vuela, al lado de la tuya. Pensaba que ARC32 usaba las mismas funciones del ACE.
Yo, utilizo SQL de manera nativa con ADS, es realmente comodo y muy potente.

Haber que resultados sacas de tu investigacion, por otra parte estaria analizar el codigo fuente de ARC y/o hacer un peque~no ejemplo con Delphi que haga la misma consulta para ver si se optiene o no la misma velocidad del ARC, si es asi, significaria que el problema esta en la implementacion del API de ADS en xHarbour o Harbour o que falta algun parametro u opcion en la aplicacion, quien sabe RF pueda darnos ideas

saludos

Marcelo

Posted: Tue May 02, 2006 3:30 pm
by R.F.
Carles:

Una pregunta.... y creo que tiene que ver con la forma en que estas trabajando.... ¿tienes indice asignado para esa tabla DBF ?

Posted: Wed May 03, 2006 7:42 am
by Carles
Hola a todos,

Marcelo:

1.- He probado en ADSCreateSQLStatement("SQLarea",2), todos los parametros posibles, y realmente solo funciona con el 2 (ADS_CDX)
Yo, utilizo SQL de manera nativa con ADS, es realmente comodo y muy potente.
Pero de manera nativa, te refieres instalando el driver ODBC, no ?. Justamente, quiero evitar q el cliente se tenga de instalar y parametrizar el Odbc.

Quizas otra manera seria probar la coña del ADO, pero me parece q tambien implica instalar en cada cliente algun componente, no se , no experimentado. Habeis hecho alguna prueba con ADO con reultado satisfactorio ? (siempre hablamos de ADS, eh :wink: )

Rene:

El ejemplo de arriba tanto si lo ejecutas con una tabla con indice como sin indice, tarda lo mismo. Uhmm no se. Quizas me estoy metiendo en un tema q no tiene solución.

Todo parte de la idea que desde un solo exe, obtener esta potente funcionalidad como hace el ARC32. Tendre obsesion con este tipo :shock:

Gracias por vuestras ideas.

Posted: Wed May 03, 2006 10:10 am
by Carles
Hola,

He instalado el ODBC de ADS para realizar test. El resultado sobre 100000 registros es para la Sql "Select first, last, age from test where age > 90"

1.- Si quiero los una pagina de 30 registros -> 0.2 seg.
2.- Si selecciono todos los registros de la condicion (11.000 +-) -> 2.5 seg.

El driver de ADS realmente va muy rapido, pero se sale del objetivo de jugar con las funciones nativas.

Posted: Wed May 03, 2006 11:26 am
by fgondi
Hola Carles,

Por dos motivos va mas rapido ARC32 que el programa.

1. La consultas SQL "Select * from Test where age > 90" no necesita hacer una sql. Lo que hace es abrir la tabla ADT con un filtro. Se puede comprobar si hace esto, porque los nombres de _ aparecen en mayúscula. En caso contrario, necesita ejecutar la SQL, se ven en minúscula

2. y mas importante. En caso de tener que hacer la SQL devuelve sólo los primeros 20 +- registros. Al dar Ctrl+Fin calcularía toda la sql y se vería el tiempo real que tarda.

Recuerda que al ejecutarlo con ADSExecuteSQLDirect, lo que tiene que hacer es ejecutar toda la sql, no sólo los 20 primeros registros y introducirlos en un tabla temporal para poder usarlo en el programa.

Posted: Wed May 03, 2006 11:56 am
by Carles
Hola Fernando,
Por dos motivos va mas rapido ARC32 que el programa.

1. La consultas SQL "Select * from Test where age > 90" no necesita hacer una sql. Lo que hace es abrir la tabla ADT con un filtro...
Entiendo q ARC32 abre una tabla en formato ADT ? Como puede ser si la tabla es una dbf normal y corriente ? No se si me explico. Cuando tu haces una query normal...

Image

arc32 no creo q abra la dbf y le pone un filtro. O si ? Tampoco creo q abra usando ODBC porque si no tienes el driver instalado funciona igual. Mi pregunta es, como poder emular la velocidad de arc32 sin tener q usar ODBC y ADO. Crees q se puede ?

Gracias por tu opinion

Posted: Wed May 03, 2006 4:51 pm
by fgondi
Hola,

Aunque lo que abras sea una dbf, lo que abres es la DBF, no una consulta sobre la DBF. Esto lo hace si trabajas en modo Server, no en modo local.

Comprueba como, por ejemplo, te deja cambiar los valores que te ha devuelto. Si fuera una SQL no permitiría cambiar los valores.

Prueba ejecutando:
"Select {STATIC} frist, last, street, age FROM test WHERE age>90".
o cualquier consulta que unas tablas, esas no se dejan editar.

Code: Select all

Mi pregunta es, como poder emular la velocidad de arc32 sin tener q usar ODBC y ADO. Crees q se puede ?
Yo no conseguí lograrlo.

De todas formas, recuerda que tiene que generar una DBF temporal para devolverto en el alias que indicas, y ahí es donde esta el tiempo. Cuando mas campos pidas y mas registros tenga de devolver mas lento irá.

Mi consejo:
Pide _ indices, única y exclusivamente en la consulta. Luego el resto de los datos optenlos a traves de buscarlos en la DBF original

Code: Select all

LOCAL consulta := "Select frist from Test where age > 90"

Code: Select all

FOR nI := 1 TO 20 
     Test->( DbSeek(SqlArea->Frist) )
     cTxt += sqlarea->first + ' ' + Test->last + ' ' + Test->street + ' ' + str( Test->age ) + CRLF 
     sqlarea->( DbSkip() ) 
NEXT 
Siendo "Test" el alias de la dbf previamente abierta sin ningun tipo de filtro aplicado y "frist" el campo indice de la misma