Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 02-03-2010
Avatar de erickahr
erickahr erickahr is offline
Miembro
 
Registrado: feb 2010
Posts: 94
Poder: 15
erickahr Va por buen camino
Consultas IBQuery

Hola a todos y gracias de antemano, tengo una tabla de firebird de la cual debo eliminar una gran cantidad de registros (+ de 1000,000 ), la cosa es que la eliminacion me va muy lenta, quisiera saber si hay una forma mas rapida de hacerlo o como me recomiendan relizar la eliminacion, mi codigo esta algo asi:

select * from remision where fecha <= :xFecha;



luego de filtrar hago la eliminacion mediante un



while not EOF do
begin
delete;
next;
end;




funciona todo bien pero lo he dejado correr mas de 3 horas y no termina... segun mis calculos elimina 1000 registros en aproximadamente una hora ...
ojala me puedan ayudar...
__________________
Nadie puede separar su fe de sus actos, o sus creencias de sus afanes
Responder Con Cita
  #2  
Antiguo 02-03-2010
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Y, ¿por qué no usas una consulta DELETE?

Código SQL [-]
delete from remision where fecha <= :xFecha

// Saludos
Responder Con Cita
  #3  
Antiguo 02-03-2010
Avatar de erickahr
erickahr erickahr is offline
Miembro
 
Registrado: feb 2010
Posts: 94
Poder: 15
erickahr Va por buen camino
Gracias por tu pronta respuesta... de hecho fue mi primer opcion pero al ver la problematica (lentitud) estuve leyendo po ahi y encontre el bucle, y hago un commit cada 1000 registros para no saturar el cache.. pero aun asi sigue lentisimo y solo quiesiera saber si hay otro metodo ojala tengas algo , gracias otra vez

Código Delphi [-]
procedure TfrMain.CortaRem;
var
Cadena: String;
begin
  Cadena:='Select * From Remision Where Fecha <= :xValue';
  Transaccion.Active:=True;
  with IBQuery1 do
    begin
    SQL.Clear;
    SQL.Add(Cadena);
    ParamByName('xValue').AsDate := dtVentas.Date;
    try
      active:=true;
      dbgrid1.Enabled:=true;
      first;
      while not EOF do
        Begin
        Delete;
        Conta:=Conta+1;
        Next;
        if conta>100 then
          Begin
          Conta:=0;
          Transaccion.Commit;
          CortaRem;
          end;
        end;
      Transaccion.Commit;
    except
      on E: Exception do
        begin
        Application.MessageBox( PChar( E.Message ), 'Error de SQL', MB_ICONSTOP );
        Transaccion.Rollback;
        end;
    end;
  end;
end;
__________________
Nadie puede separar su fe de sus actos, o sus creencias de sus afanes

Última edición por roman fecha: 02-03-2010 a las 02:02:33. Razón: Agregar etiquetas [delphi para mayor legibilidad del código
Responder Con Cita
  #4  
Antiguo 02-03-2010
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Bueno, mira, yo no conozco Firebird pero podría jurar que la consulta DELETE siempre va a ser más rápida y eficiente que un ciclo, pues este ciclo, muy posiblemente se limite a hacer un DELETE sobre cada uno de los registros.

Ahora bien, aunque, como te digo, no conozco Firebird, se me ocurren dos considerandos generales que podrían ayudar: primero asegurarte que tu tabla tiene un índice sobre el campo fecha, pues de esta manera, el motor encontrará mucho más rápido los registros que debe borrar. Segundo, si lo anterior no funciona, entonces quizá debas probar desactivando los índices. Toma en cuenta que si tu tabla tiene definidos muchos índices, todos ellos deben actualizarse al borra registros.

// Saludos
Responder Con Cita
  #5  
Antiguo 02-03-2010
Avatar de ContraVeneno
ContraVeneno ContraVeneno is offline
Miembro
 
Registrado: may 2005
Ubicación: Torreón, México
Posts: 4.738
Poder: 23
ContraVeneno Va por buen camino
pues no se lo que los demas opinen, pero creo que un ciclo While con su respectiva transacción (commit) es mil veces más lenta que la instrucción delete que propone maese Roman....

__________________

Responder Con Cita
  #6  
Antiguo 02-03-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hombre está claro que un DELETE va a ir más rápido que un WHILE, puesto que al primero le dejas total libertada al motor SQL para definir el recorrido del borrado, etc. ...

Pero la diferencia será mínima, y desde luego no puede explicar una demora de horas para hacer ese borrado.

En mi opinión estoy convencido de que tu problema vienen dado por los triggers que tienes en esa tabla. Cada vez que borras un registro (independientemente de si lo has borrado con un DELETE o mediante un bucle), se dispara el trigger correspondiente, el cual debe hacer un montón de cálculos, por lo que parece. Si esto lo multiplicas por los 100.000 registros que quieres borrar, pues de ahí viene esa lentitud.

Resumiendo, olvídate de como haces el borrado y examina lo que hacen los triggers que se disparan para cada registro borrado. Quizás quieras desactivar esos triggers antes de empezar el borrado.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #7  
Antiguo 03-03-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Evidentemente el "delete" es más rápido que el bucle, pero estoy con guillotmarc en que deben existir triggers o procedimientos que se ejecutan al borrar, debes desactivarlo antes y verás que se borra todo en un "santiamén"
Responder Con Cita
  #8  
Antiguo 03-03-2010
Avatar de erickahr
erickahr erickahr is offline
Miembro
 
Registrado: feb 2010
Posts: 94
Poder: 15
erickahr Va por buen camino
Talking Gracias a todos, Sobre todo a ROMAN!!!

Pues muchas gracias a todos por sus respuestas, y por su tiempo... en realidad Roman tuvo la razon desde el principio, el Delete fue la mejor opcion, solo que tenia un problma con las PrimaryKey, estaban desordenadas, al checarlas las arregle y corrio del 1, los triggers no los puedo desactivar como aconseja casimiro, porque los necesito para eliminar registros de una tabla relacionada a remision, pero arreglando las llaves primarias y los indices, bajo de 8 horas a un par de segundos, "Roman cuando sea grande quiero ser como tu" jaja, saludos y gracias.
__________________
Nadie puede separar su fe de sus actos, o sus creencias de sus afanes
Responder Con Cita
  #9  
Antiguo 03-03-2010
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Felicidades por resolver el problema, pero la explicación que has dado es errónea, puede llevar a confusión a otra persona que llegue hasta aquí por un problema similar.

Algo más de lo que te sugirió Román has hecho, puesto que lo que dices no tiene sentido, es harto difícil de creer.

Es imposible que un delete from remision where fecha <= :xFecha te tarde ocho horas, añadas un índice sobre el campo Fecha (que es el índice que te sugirieron crear ya que es el único campo que interviene, no la clave primaria) y milagrosamente ese borrado pase a tardar dos segundos.

Simplemente no puede ser, si el motor SQL no encuentra un índice para Fecha, se ve obligado a recorrer toda la tabla buscando las fechas menores a cierto valor. Pero eso puede tardar un par de minutos (como máximo), nunca ocho horas.

NOTA: Resulta evidente que has solucionado el problema mediante índices sobre las tablas secundarias que son borradas en triggers. Así que no te equivoques, tu problema estaba en esos triggers, en lo que tardaban en ejecutarse al no estar debidamente optimizados (lo cual, como te dijimos, multiplicado por 100.000 registros a borrar, es lo único que puede explicar un tiempo de ejecución de ocho horas).

PD: Las Primary Keys siempre están ordenadas, puesto que siempre existe un índice para la clave primaria que definas en la tabla (ese índice lo crea automáticamente el sistema). Tú te estas refiriendo a que has creado índices para las Foreign Keys, es decir, las referencias en tus tablas secundarias que apuntan a la tabla a borrar.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 03-03-2010 a las 17:32:19.
Responder Con Cita
  #10  
Antiguo 03-03-2010
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Yo concuerdo con marc; hay algo que no termina de cuadrar. ¿Cómo está eso de que las llaves primarias estaban desordenadas? Una llave primaria no puede estar desordenada, o qué motor de pacotilla es Firebird .

Creo, como marc, que seria conveniente que explicaras con más detalle lo que hiciste para resolver el problema.

// Saludos
Responder Con Cita
  #11  
Antiguo 03-03-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.043
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Desde luego, una primary key desordenada... como que no
Responder Con Cita
  #12  
Antiguo 03-03-2010
Avatar de erickahr
erickahr erickahr is offline
Miembro
 
Registrado: feb 2010
Posts: 94
Poder: 15
erickahr Va por buen camino
Red face Sorry!!!

OK si perdon, creo que no me explique bien, al decir las
Cita:
PK estaban Desordenadas
no me referia al orden de los registros, sino a que mi declaracion de PK e Indices era incorrecta, a continuacion les muestro como tengo creadas las PK y los indices:

TABLA DE_REM
Código SQL [-]
ALTER TABLE DE_REM ADD CONSTRAINT PK_DE_REM PRIMARY KEY (IDTIENDA, IDREMISION, ID);
CREATE INDEX DE_REM_IDX1 ON DE_REM (IDARTICULO);

TABLA REMISION
Código SQL [-]
ALTER TABLE REMISION ADD CONSTRAINT PK_REMISION PRIMARY KEY (IDTIENDA, IDREMISION);

Los Scripts que muestro son los definitivos, como ha funcionado mi consulta rapidamente, el problema radicaba en que tenia mal declarados los PK e Indices.

ejemplo:

En la tabla remision tenia algo asi:
(IDTIENDA, IDREMISION);
En la tabla de_rem :
(ID, IDREMISION, IDTIENDA);
Segun lei, al hacer esto era como si no existieran los indices ni nada, tenia que declararlos con el mismo orden en las dos tablas.

el Trigger implicado es este:

Código SQL [-]
SET SQL DIALECT 3;
SET NAMES NONE;

SET TERM ^ ;

CREATE TRIGGER REMISION_DEL FOR REMISION
ACTIVE BEFORE DELETE POSITION 0
AS
begin
Delete from de_rem
  where idTienda = Old.idTienda and idRemision = Old.idRemision;
end
^

SET TERM ; ^

Una disculpa nuevamente a todos, y
Cita:
no me regañen que soy nuevo aki XD
GRACIAS de nuevo!!!
__________________
Nadie puede separar su fe de sus actos, o sus creencias de sus afanes
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 SQL V.S. Consultas Clipper AGAG4 SQL 7 20-12-2005 15:59:31
Refresh de un IBQuery perillan Conexión con bases de datos 1 28-08-2005 20:43:12
Filter en IBQuery StartKill Firebird e Interbase 1 27-08-2005 06:51:06
IBDataSet - IBQuery dmagui Firebird e Interbase 0 14-06-2005 16:24:40
query Vs. IBquery Eolo Conexión con bases de datos 0 11-02-2004 18:54:24


La franja horaria es GMT +2. Ahora son las 14:29:17.


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