Hola,
Finalmente pude realizar mis testeos y aquí os mando un resumen. Si alguien cree q estoy errado o quiere ampliar en algo, le agradeceria q lo posteara.
Un cursor es el controlador de una tabla que se ha producido como consecuencia de realizar una consulta via SQL. Estos cursores los podemos diferenciar como dinamicos o estaticos. Dichos cursores los podemos gestionar como los controladores de una tabla y su funcionalidad es la misma.
El hecho de usar la funcion AdsExecuteSqlDirect(), hace que ADS trabaje de 2 posibles maneras.
a.- Cursor dinamico. Si puede aplicar un filtro a la tabla, crea una vista con _ implicados y devuelve el cursor. Es posible la modificacion del registro.
b.- Cursor estatico. Se crea una tabla con _ implicados y rellena los registros con los que cumplen la sql. No es posible su modificacion.
Es posible en algun caso forzar un cursor estatico poniendo la clausula {estatic}. Mas adelante describo un caso en que es aconsejable su uso
Que diferencias, sin embargo, existen entre un tipo de cursor y otro., El cursor estatico es mas lento de crearse porque se crea la tabla y se rellena con los registros resultantes pero en la consulta podemos usar (sacado del help de ads):
• DISTINCT in the SELECT clause
• Joins (inner, outer, self, or UNION)
• Any aggregate function
• GROUP BY or HAVING clauses
• Subqueries
• Certain scalar functions (see Scalar Functions in a WHERE Clause)
• If a memo field is used in a WHERE clause (e.g., WHERE memo is null)
• LIKE operator is used in a WHERE clause (e.g.,. WHERE lastname LIKE 'Smith%)
• Expressions or scalar functions in the select list (e.g., select UCASE(lastname) … )
• TOP in the SELECT clause
Es logico pensar que si no usamos una de estas clausulas, crear un filtro en la tabla via DbSetFilter(), es lo mejor, pero tenemos de analizar _ en que aplicar un sistema u otro en funcion del tamaño de la tabla, el numero de aciertos conseguidos y el tipo de consulta:
Los test realizados son a partir de la tabla Test.dbf con 1 millon de registros. En el test, se intenta:
1.- Aplicar un DbSetFilter() y AdsExecuteSqlDirect() (en algun caso forzar la consulta statica).
2.- Consulta sobre un campo normal y con indice
3.- En el caso en que hay 3 registros de resultado se han insertado previamente en el registro 1, 500000 y 1000000.
Los resultados los tengo en una hoja excel y los he intentado plasmar en un fichero txt. Espero que se entienda.
Code: Select all
****
Test
****
Id Reg
aprox Index Funcion Consulta
-- ----- ----- --------------------- -----------------------------------------------------------------------------------
1 2200 AdsExecuteSQLDirect() Select first, last,state, age from test where age > 90
2 AdsExecuteSQLDirect() Select {static} first, last,state, age from test where age > 90
3 DbSetFilter() age > 90
4 80000 first AdsExecuteSQLDirect() Select first,last,state, age form test where first >= 'A' and first <= 'B'
5 AdsExecuteSQLDirect() Select {static} first,last,state, age form test where first >= 'A' and first <= 'B'
6 DbSetFilter() first >= 'A' .and. First <= 'B'
7 AdsExecuteSQLDirect() Select first,last,state, age form test where last >= 'A' and last <= 'B'
8 AdsExecuteSQLDirect() Select {static} first,last,state, age form test where last >= 'A' and last <= 'B'
9 DbSetFilter() last >= 'A' .and. last <= 'B'
10 3 first AdsExecuteSQLDirect() select first, last, state, age from test where first = 'Dummy'
11 AdsExecuteSQLDirect() select {static} first, last, state, age from test where first = 'Dummy'
12 DbSetFilter() first = 'Dummy'
13 AdsExecuteSQLDirect() select first, last, state, age from test where last = 'Dummy'
14 AdsExecuteSQLDirect() select {static} first, last, state, age from test where last = 'Dummy'
15 DbSetFilter() last = 'Dummy'
16 8648 first AdsExecuteSQLDirect() Select * from test where first like 'Fra%'
17 AdsExecuteSQLDirect() Select {static} * from test where first like 'Fra%'
18 DbSetFilter() ***
19 AdsExecuteSQLDirect() Select * from test where last like 'Fra%'
20 AdsExecuteSQLDirect() Select {static} * from test where last like 'Fra%'
21 DbSetFilter() ***
22 3 first AdsExecuteSQLDirect() Select * from test where first like 'Fra%'
23 AdsExecuteSQLDirect() Select * from test where last like 'Fra%'
24 DbSetFilter() ***
**********
Resultados
**********
Id Tiempo Listar
Funcion 100 reg. Browse() Update Trafico
-- ------- -------- -------- ------ -------
1 38,72 0,03 Muy Lento Si Si
2 8,34 0,03 Rapido
3 0,02 0,01 Rapido Si
4 26,99 0,03 Muy Lento Si Si
5 3 0,03 Rapido
6 0,02 0,02 Rapido Si
7 9,31 0,03 Muy Lento Si Si
8 3,88 0,03 Rapido
9 0 0,02 Rapido Si
10 0,03 0,09 Lento Si Si
11 0,01 0 Rapido
12 0,01 1,59 Lento Si
13 1,73 0,09 Lento Si Si
14 12,88 0 Rapido
15 0,03 8,63 Lento Si
16 0,05 0,03 Rapido
17 2,91 0,03 Rapido
18
19 16,33 0,03 Rapido
20 17,92 0,03 Rapido
21
22 0,03 0,02 Rapido
23 16,34 0,02 Rapido
24
Es curioso al final, como mi principal obsesion, que era la de ir ‘rapido’ como Arc32 se ha cumplido.
Code: Select all
1.- En el caso de la busqueda last = ‘Dummy’ (3 registros):
Arc32 9.2
DbSetFilter() 8.63
2.- En el caso de la busqueda first = ‘Dummy’ (3 registros con indice)
Arc32 0.33
AdsExecuteSqlDirect() 0.32
3.- En el caso first = ‘Fra%’ (indice)
Arc32 0.04
AdsExecuteSqlDirect() 0.05
4.- En el caso last = ‘Fra%’
Arc32 17.78
AdsExecuteSqlDirect() 16.33
Todo depende de q funcion usar y para que (si queremos porcesar en tablas internas, en browse,…). Gracias Fernando y Marcelo por vuestra ayuda. Si alguien quiere el programa de test para ampliar sus testeos, que me lo pida que se lo mandare.
Nota: No queria dormir a nadie, pero es lo q hay...