Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Comenzando con DBX (https://www.clubdelphi.com/foros/showthread.php?t=81226)

Gherardo 23-10-2012 20:25:29

Comenzando con DBX
 
Hola a todos, hasta ahora siempre he utilizado los componentes BDE para acceder a datos y estoy empezando a probar con DBX, y ando un poco perdido.
La primera prueba que he realizado ha sido rellenar un DBGrid con los datos de una tabla, comparando velocidades entre BDE y DBX, y resulta que con un TTable (BDE) Obtengo todos los datos en 0,6 segundos. y con un clientDataSet 26 segundos.
Utilizo la misma tabla de la misma base de datos en SQL Server 2008.
Yo tenia entendido que DBX era mas rapido, ¿Que puedo estar haciendo mal?.

Gracias por anticipado.

Casimiro Notevi 23-10-2012 20:41:08

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración :)

Cita:

Empezado por Gherardo
Yo tenia entendido que DBX era mas rapido, ¿Que puedo estar haciendo mal?.

Como comprenderás, no somos adivinos, así que tendrás que explicarnos qué haces, cómo, etc.

Y recuerda poner títulos descriptivos a tus preguntas, "Comenzando con DBX" no describe lo que preguntas.

De todas formas te anticipo que, efectivamentte, DBX es bastante rápido.

Gherardo 23-10-2012 20:56:19

Gracias Casimiro por tu repuesta.

Lo que hago es conectar un un Dbgrid a una tabla de SQL Server 2008, esta tabla tiene unos 120.000 registros.
La conecto a traves de un TTable , TDatabase y un TDataSource, y en el onClick de un TButton pongo "TTable.Active:=True;" de esta manera
veo los datos en menos de un segundo.

Despues realizo la misma operación pero utilizando un TSQLConnection,TSQLTable,DataSetProvider,ClientDataSet y en el evento on Click del TButton "ClientDataSet.Active:=True;" pero esta vez tarda entre 20 y 26 segundos en aparecer los datos.

Todo se encuentra en el mismo ordenador, por ahora son pruebas y las realizo en local.

No se que puedo estar haciendo mal, pues no creo que pueda haber esa diferencia de velocidad.

Gracias.

Casimiro Notevi 23-10-2012 21:24:31

¿Pero para qué quieres 120000 registros en una tabla?, ¿los vas a leer todos? :confused:

Al González 24-10-2012 03:47:05

Hace muchos años que no manejo el obsoleto BDE pero, por la diferencia de tiempos que Gherardo señala, es casi seguro que TTable no esté trayendo esos 120 mil registros "de un jalón", es decir, que probablemente está haciendo "paginación" (se trae un grupo de registros y luego el siguiente según se necesiten).

Para salir de dudas, Gherardo, coloca una instrucción "Tabla.Last" después de poner en True su propiedad Active. En ese caso TTable habrá de demorar algo más.

Con TClientDataSet también pueden traerse registros en paquetes de n filas según vaya necesitando avanzar el cursor (propiedad PacketRecords). No obstante, prefiero traerme de un solo golpe todos los registros de la consulta (dejando PacketRecords en -1), dado que no es muy buena práctica "entretener" al servidor con impredecibles acciones de la interfaz de usuario.

Y bueno, si realmente se necesita una consulta de 120 mil registros, debemos acostumbrarnos a que algo así no es gratis (al menos no con los equipos actuales). :)

Gherardo 24-10-2012 09:19:17

Muchas gracias AL Gonzalez.

Una vez que tienes todos los registros "aquì", el Last es instantaneo en ambos casos.

Si cambio la propiedad PackectRecords del ClientDataSet a un valor distinto a -1, en este caso si hay retardo en el Last del clientDataSet, esto no me preocupa, pero me da un error al realizar un ApplyUpdate. El error dice lo siguiente: " no se puede crear una nueva transacción, se excedio la capacidad ".

Gracias.

Al González 24-10-2012 16:24:33

Cita:

Empezado por Gherardo (Mensaje 447821)
Una vez que tienes todos los registros "aquì", el Last es instantaneo en ambos casos.

Ajá, pero ¿cuánto tiempo tarda en ejecutarse ese Last con TTable (apenas hecha la apertura)? ¿Cuánto tarda si en lugar de Last recorres su cursor registro por registro (clásico "While Not EOF Do Next")? (Esto último es lo que hace el Proveedor con el objeto consulta para darte todos los registros al TClientDataSet).

Sobre PacketRecords, como dije antes, es preferible dejarla en -1. :)

roman 24-10-2012 16:46:24

Cita:

Empezado por Al González (Mensaje 447841)
Ajá, pero ¿cuánto tiempo tarda en ejecutarse ese Last con TTable (apenas hecha la apertura)?

En realidad sí es "instantáneo". El punto aquí, es que el compañero está haciendo pruebas en local y no es de asombrar que el BDE "gane" aquí.

Aunque de todas formas extraña tanto tiempo para dbx siendo una base local.

// Saludos

Al González 24-10-2012 17:23:33

Esperemos a ver qué nos dice sobre la prueba de recorrido con "While Not EOF".

Y es que estrictamente hablando, DBX (dbExpress) son los componentes TSQLXXX (conexión y consulta). TClientDataSet no es parte de DBX (hay que erradicar ese mito). TClientDataSet, de la pestaña "Data Access", es un conjunto de datos genérico muy bueno para diversos escenarios, entre ellos conectarse a DBX, o a cualquier otro grupo de componentes de datos, usando un objeto TDataSetProvider (también de la pestaña "Data Access").

El cursor unidireccional de TSQLQuery (y sus similares de la familia DBX) debe ser mucho más rápido que un cursor bidireccional como TTable. Pero el trabajo del TDataSetProvider más el enriquecido cursor de TClientDataSet sí que van a añadirle algo de CPU a la carga de esa tabla.

Sin embargo, cuando me he conectado a MS SQL Server (2008, creo) con el controlador DBX para ese motor que viene en Delphi 7, he visto que el trabajo no resulta del todo óptimo, por lo cual termino usando ADO. No sé si esto se deba al hecho de estar usando un controlador muy antiguo, creado para versiones más viejas de MS SQL Server (y habría que ver que tan al día va ese controlador en las nuevas versiones de Delphi).

En resumen, DBX + TClientDataSet es una combinación muy buena con varios motores de base de datos (lo he comprobado con Firebird y no regresaría a usar IBX o similares), pero recordemos que MS SQL Server no es precisamente una base de datos que se lleve muy bien (hoy en día) con las bibliotecas de conexión pertenecientes a otras empresas.

Las preguntas que le hago a Gherardo van encaminadas a descubrir qué tanto se debe esa tardanza al controlador, qué tanto a DBX y qué tanto a TClientDataSet.

Saludos. :)

roman 24-10-2012 17:44:37

Cita:

Empezado por Al González (Mensaje 447848)
Esperemos a ver qué nos dice sobre la prueba de recorrido con "While Not EOF".

En la prueba que he hecho, usando una tabla Paradox de aproximadamente 100,000 registros, ambos casos, Last y ciclo son instantáneos.

Como dije antes, creo que se está desestimando aquí el hecho de tratarse de un acceso local en el cual el BDE lleva las de ganar puesto que el acceso se hace directamente sobre el archivo físico de la tabla.

// Saludos

gatosoft 24-10-2012 18:01:14

Al final de cuentas, el punto clave aqui amigo Gherardo es lo que pregunta Casimiro:

Cita:

Empezado por Casimiro Notevi (Mensaje 447790)
¿Pero para qué quieres 120000 registros en una tabla?, ¿los vas a leer todos? :confused:

Para algunos (me incluyo) se considera una mala práctica la utilización de componentes TTable para hacer CONSULTAS o Administración de datos.... estos componentes son váidos cuando las tablas son pequeñas o no transaccionales... pero es evidente que 120.000 registros corresponden a una tabla con movimientos....

Te aconsejo replantear tu modelo, de manera tal que el usuario proporcione un filtro a la consulta, o que utilices un esquema de paginación... no se...

BDE es una tecnología que en su momento fue la respuesta a muchos problemas, pero hace años que no tiene soporte, por lo cual urge que te salgas de ahí... si quieres un futuro para tu sistema. Cuando pienses en BDE, piensa en el equivalente de estar instalando a tu usuario el sistema operativo Windows 95...


A medida que vayas entrando en DBX vas a encontrar sus bondades...

Un saludo,

Al González 24-10-2012 18:07:05

Gracias por confirmarlo, Román. :)

Cita:

Empezado por roman (Mensaje 447850)
[...] un acceso local en el cual el BDE lleva las de ganar puesto que el acceso se hace directamente sobre el archivo físico de la tabla.

Con Paradox lo encontraría lógico, pero con SQL Server no imagino al BDE accediendo directamente al archivo MDF (o cual sea que fuese la extensión).

Creo que me estoy perdiendo de algo...:confused:

roman 24-10-2012 18:07:33

Cita:

Empezado por gatosoft (Mensaje 447851)
Al final de cuentas, el punto clave aqui amigo Gherardo es lo que pregunta Casimiro:

Coincido contigo. Desafortunadamente es un vicio que quedó de la época en que se usaban las bases de escritorio y podía uno darse el lujo de tener los 120,000 registros "en la mesa" sin pestañear. Luego se da uno cuenta que se trataba de un lujo por demás innecesario (como la mayoría de los lujos ;)).

// Saludos

Gherardo 24-10-2012 20:24:04

Gracias a todos

He hecho la prueva del " while not eof" y el resultado ha sido , con el BDE 10 Segundos.
Con dbx Cuando llevaba 20 minutos me he cansado y he reseteado el programa, con lo cual no se lo que tarda.

el codigo que he utilizado es el siguiente.

Código:

procedure TForm1.Button1Click(Sender: TObject);
begin
    If CDSAlbaranes.Active then
 begin
    CDSAlbaranes.Active:=False;
//    CDSLineasAlbaran.Active:=False;
 end
 else
 begin
    CDSAlbaranes.Active:=True;
//    CDSLineasAlbaran.Active:=True;
  ShowMessage('Empiezo');
  CDSAlbaranes.First;
  while not CDSAlbaranes.Eof do
  begin
  CDSAlbaranes.Next;
  end;
  ShowMessage('Termino');
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    If TblCabeceraAlbaran.Active then
 begin
    TblCabeceraAlbaran.Active:=False;
//    TblLineasalbaran.Active:=False;
 end
 else
 begin
    TblCabeceraAlbaran.Active:=True;
//    TblLineasalbaran.Active:=True;
  ShowMessage('Empiezo');
  TblCabeceraAlbaran.First;
  while not  TblCabeceraAlbaran.Eof do
  begin
  TblCabeceraAlbaran.Next;
  end;
  ShowMessage('Termino');
 end;
end;

Probaré lo mismo sin utilizar el clientDataSet, pero entonces ¿como puedo hacer para que el usuario pueda modificar datos?.

De todas maneras el tema es ¿como DBX siendo más actual, no es igual o mas eficiente que BDE?.

¿Debo configurar algo en los componentes DBX?, ¿que no estoy haciendo?

Saludos y Gracias por vuestras suguerencias.

roman 24-10-2012 20:43:37

Cita:

Empezado por Gherardo (Mensaje 447860)
De todas maneras el tema es ¿como DBX siendo más actual, no es igual o mas eficiente que BDE?.

Es que, en mi opinión, estás enfocando incorrectamente la pregunta. ¿Tu aplicación va a trabajar con una base de datos local? En ese caso, bien podrías quedarte con el BDE.

Pero, si como es de esperarse, tu aplicación va a usar un base montada en un servidor, entonces el BDE ni siquiera es un competidor. Y tratar de usar DBX o cualquier otra tecnología, como si fuera el BDE, con componentes Table, en este caso te dará pobres resultados.

Necesitas usar consultas SQL del tipo:

Código SQL [-]
select * from cliente where nombre like 'MONTOYA%'

es decir, con un filtro que razonablemente restrinja la cantidad de resultados.

Después de un tiempo, te darás cuenta que, en realidad, presentar los 120,000 clientes al usuario para que éste recorra la lista hasta llegar a la M y de ahí buscar Montoya, no sirve de nada. Y, a fin de cuentas, tu usuario terminará agradeciéndotelo, pues para él es más sencillo usar un formulario de búsqueda que recorrer manualmente miles de resultados.

// Saludos

Casimiro Notevi 24-10-2012 21:17:30

Cita:

Empezado por Gherardo (Mensaje 447860)
1. pero entonces ¿como puedo hacer para que el usuario pueda modificar datos?.
2. De todas maneras el tema es ¿como DBX siendo más actual, no es igual o mas eficiente que BDE?.
3. ¿Debo configurar algo en los componentes DBX?, ¿que no estoy haciendo?

1. El usuario selecciona el registro a modificar (pides su nombre, código, nif, etc. (depende del programa que estés haciendo)) y lo buscas:
Código SQL [-]
select * from tablaclientes where nif='12345678X'
Ya lo has localizado, ahora sólo haces un 'edit' para que el usuario lo modifique.

2. DBX es mucho más eficiente que BDE. El problema es que lo estás tratando como una obsoleta tabla plana ( lo que en su día era DBF, por ejemplo)

3. ¿Qué estás no haciendo?, es que debes usar cliente/servidor, es una base de datos relacional (un RDBMS), por lo tanto debes usarla como es, no quieras usar un Ferrari para transportar cajas de tomates. Los tiempos han cambiado.

Aquí tienes uno de los mejores libros que puedes encontrar para manejar bases de datos con delphi, está en pdf, es primordial.

Gherardo 24-10-2012 22:46:12

Bueno veo que tengo que cambiar la mentalidad. Empezare a ver como puedo rediseñar mi aplicación.

Gracias casimiro por el enlace del libro.

Gracias a todos.


La franja horaria es GMT +2. Ahora son las 16:54:08.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi