Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 28-12-2022
viverosjosem viverosjosem is offline
Baneado
 
Registrado: dic 2017
Posts: 64
Poder: 0
viverosjosem Va por buen camino
Angry Seleccion de datos extremadamente lenta... muero esperando..

LLevo muchos anos trabajando con delphi y Paradox. Y ahora me e visto en la necesidad de migrar a SQL. Mi experiencia con SQL, es mas bien pobre.

La situacion es la siguiente:
Tengo un cliente Chino, que tiene una fabrica de masas de hojas de wantan y arrollado primavera.

La tabla de facturas ya tiene casi 19.000 registros.
Los documentos de venta se graban en dos archivos separados: "Facturas" (contiene toda la informacion del docmento de venta: Rut, Numero, Fecha, monto, iva... etc. Cerca de 19.000 registros). Y "DetFact", detalle de facturas. (contiene: Rut, Numero, ademas del detalle de la compra: Codigo, Descripcion, cantidad.., etc. Cerca de 22.000 registros).

Lo que intento hacer, es presentar en un reporte la informacion de los clientes, sus datos de compra, lo adeudado, y los productos adquiridos.


Ejemplo:

Cliente................Factura.......Estado...............Total..........Pagado..........Saldo...... ....Descrip..........................Cantidad
Gin Sam Wan.........12341.....Pendiente........120.000.........80.000........40.000..........Masa Wantan mediano............400



Estoy usando una base de datos SQL Firebird 2.5, con delphi 2010.

Uso el siguiente codigo para hacer la consulta:

Código SQL [-]
         SQLDataSet1.Close;
         SQLDataSet1.CommandType := ctQuery;

         SQL_Text := 'SELECT  ' + 
                              'Facturas.TipoDoc, Facturas.Rut, Facturas.Numero, ' +
                              'Facturas.Estado, '     +
                              'Facturas.FechaEmi, Facturas.FecPago, ' +
                              'Facturas.Total, Facturas.Pagado, Facturas.Saldo, '  +
                              'DetFact.Codigo, DetFact.Descrip, DetFact.Cantidad '  +
                              'Clientes.Nombre, ' +
                      'FROM Facturas '                                 +
                      'LEFT JOIN Clientes '                            +
                      'ON Clientes.Codigo=Facturas.Rut ' +
                      'LEFT JOIN DetFact '                            +
                      'ON DetFact.Rut=Facturas.Rut AND DetFact.Numero=Facturas.Numero  ' +
                      'WHERE ' +
                                 'Facturas.Estado<>' + QuotedStr('A') + ' ' +
                      'ORDER BY Facturas.FechaEmi ' + ';';

   SQLDataSet1.CommandText := SQL_Text;

   SQLDataSet1.Open;
   if ( not SQLDataSet1.Eof ) then begin
     ...
     ...
     Lineas de codigo para el reporte..
     ...


El problema es, que esta consulta se demora mas de 10 minutos en arrojar resultados.

Existe alguna manera de hacer esto distinto?, para que la consulta sea mas rapida, sino automatica?.

Saludos.

Gracias de antemano.

Jose Miguel B.
Responder Con Cita
  #2  
Antiguo 28-12-2022
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Lo primero que haría sería revisar el plan de ejecución a ver en qué se está "perdiendo" ese tiempo.
No parece una consulta lo bastante compleja para que el Open tarde 10 minutos.

A partir de lo que diga el plan de ejecución se puede ver qué hacer exactamente.

De todas formas puedes revisar que:
  • Las tablas tengan los índices correspondientes, sobre todo por los campos por los que haces JOIN
  • Revisa si las LEFT JOIN, puedes convertirlas en INNER JOIN
  • Prueba a utilizar cursor unidireccional y/o sólo lectura en el Dataset (Query). Si tienes la propiedad y si te sirve para el listado.
He asumido que lo que tarda es el Ooen, pero deberías asegurarte de que no sea el While el que está consumiendo el tiempo.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 28-12-2022
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Asegúrate de que los índices son los que necesitas.
Esto es en base al SQL que ejecutas, aunque creo que quizás falten más cosas.
  • No utilizas TIPODOC en el WHERE
  • TIPODOC debería estar también en el detalle si es parte de la PK de FACTURAS

Código SQL [-]
CREATE TABLE FACTURAS (
    NUMERO    INTEGER NOT NULL,
    RUT       VARCHAR(15) NOT NULL,
    TIPODOC   VARCHAR(15),
    ESTADO    INTEGER,
    FECHAEMI  DATE,
    FECPAGO   DATE,
    TOTAL     DOUBLE PRECISION,
    PAGADO    SMALLINT,
    SALDO     DOUBLE PRECISION
    /*
    ...
    */
);

ALTER TABLE FACTURAS ADD CONSTRAINT PK_FACTURAS PRIMARY KEY (NUMERO, RUT);

/* Para la parte WHERE FACTURAS.ESTADO <> :ESTADO */
CREATE INDEX FACTURAS_IDX1 ON FACTURAS (ESTADO);

CREATE TABLE DETFACT (
    NUMERO    INTEGER NOT NULL,
    RUT       VARCHAR(15) NOT NULL,
    LINEA     INTEGER NOT NULL,
    CODIGO    VARCHAR(15),
    DESCRIP   VARCHAR(60),
    CANTIDAD  INTEGER
    /*
    ...
    */
);

ALTER TABLE DETFACT ADD CONSTRAINT PK_DETFACT PRIMARY KEY (NUMERO, RUT, LINEA);

/* Puede ser una Foreign Key o un índice */
/* Para el join: ON DETFACT.RUT = FACTURAS.RUT AND DETFACT.NUMERO = FACTURAS.NUMERO */
ALTER TABLE DETFACT ADD CONSTRAINT FK_DETFACT_1 FOREIGN KEY (NUMERO, RUT) REFERENCES FACTURAS (NUMERO, RUT);


CREATE TABLE CLIENTES (
    CODIGO  VARCHAR(15) NOT NULL,
    NOMBRE  VARCHAR(60)
    /*
    ...
    */
);

/* Para el join: ON CLIENTES.CODIGO = FACTURAS.RUT */
ALTER TABLE CLIENTES ADD CONSTRAINT PK_CLIENTES PRIMARY KEY (CODIGO);

Código SQL [-]
SELECT FACTURAS.TIPODOC, FACTURAS.RUT, FACTURAS.NUMERO, FACTURAS.ESTADO, FACTURAS.FECHAEMI, FACTURAS.FECPAGO,
       FACTURAS.TOTAL, FACTURAS.PAGADO, FACTURAS.SALDO, DETFACT.CODIGO, DETFACT.DESCRIP, DETFACT.CANTIDAD,
       CLIENTES.NOMBRE
FROM FACTURAS
LEFT JOIN CLIENTES ON CLIENTES.CODIGO = FACTURAS.RUT
LEFT JOIN DETFACT ON DETFACT.RUT = FACTURAS.RUT AND DETFACT.NUMERO = FACTURAS.NUMERO
WHERE
FACTURAS.ESTADO <> :ESTADO
ORDER BY FACTURAS.FECHAEMI


Si presentas la estructura completa de estas tres tablas quizás podamos ayudarte un poco más.
Responder Con Cita
  #4  
Antiguo 28-12-2022
viverosjosem viverosjosem is offline
Baneado
 
Registrado: dic 2017
Posts: 64
Poder: 0
viverosjosem Va por buen camino
Talking

Hola a todos.
Agradesco el tiempo y la molestia que se han tomado para contestar.

Duilioisola, tienes razon. Diste en el clavo.
Cita:
TIPODOC debería estar también en el detalle si es parte de la PK de FACTURAS".
Pase por alto el campo "TipoDoc", en el detalle de Facturas. Lo e incorporado, y ahora la consulta es automatica.

Muchas gracias por sus respuestas.

Saludos.
Jose Miguel.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Consultas extremadamente lentas en Delphi y rapidicimas en PL/SQL(ORACLE) pnsd_89 Conexión con bases de datos 13 01-07-2011 09:55:07
La pelicula que estabas esperando! mamcx Humor 2 08-06-2010 16:55:05
Ayuda con consulta lenta, lenta, lenta Gregory Mazon Firebird e Interbase 22 27-06-2007 09:56:38
Ejecutar un programa esperando o no a que termine dec Trucos 0 30-06-2006 14:05:39


La franja horaria es GMT +2. Ahora son las 19:14:18.


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
Copyright 1996-2007 Club Delphi