/ / ¿Cómo mejorar la inserción de datos / actualizar el rendimiento? - sql-server, performance, delphi, delphi-7, ado

¿Cómo mejorar el rendimiento de inserción / actualización de datos? - sql-server, performance, delphi, delphi-7, ado

Necesito mejorar el rendimiento de la carga de datos. El algoritmo actual hace una selección completa de una tabla:

select Field1, Field2,...,FieldN from Table1 order by FieldM

Los nuevos datos se leen de un archivo de texto (por ejemplo,línea de archivo de texto por fila de datos). La tabla tiene una clave principal, que contiene dos campos. Para cada línea de un archivo de texto, ubica la fila necesaria por estos dos campos (es decir, la clave principal).

query.Locate("Field1;Field2",VarArrayOf([Value1,Value2]),[]);

Si Locate devoluciones True, edita la fila, de lo contrario añade una nueva.

Por lo tanto, en cuanto a la tabla consta de aproximadamente 200000 filas, cada una Locate la operación toma cierta cantidad de tiempo ... por lo que se las arregla para actualizar alrededor de 5-6 filas por segundo.

¿Qué cosas debo considerar para mejorarlo?

Probablemente reemplace la localización a través de esta gran selección con consultas separadas?

Respuestas

10 por respuesta № 1

NO use Localizar (). Si usa localizar (), entonces Delphi busca la fila en el lado del cliente, simplemente escaneando el conjunto de filas de su consulta lleva mucho tiempo.

Si tienes acceso a MSSQL para crear almacenadolos procedimientos luego crean el siguiente procedimiento y simplemente ejecútelo para cada línea desde su archivo TEXT sin ninguna condición (Use TAdoStoredProc.ExecProc en Delphi). Entonces, en este caso, no necesita primero seleccionar y localizar el procedimiento. Actualiza el registro si se encuentran Filed1 y Field2 e inserte si don "t.

CREATE PROCEDURE dbo.update_table1
@Field1 int, --key1
@Field2 int, --key2
@Field3 int, -- data fileds
@Field4 int

AS

SET NOCOUNT ON
update table1 set Field3=@Field3,Field4=@Field4
where Field1=@Field1 and Field2=@Field2;
IF(@@Rowcount=0)
BEGIN
insert into table1(Field1,Field2,Field3,Field4)
values (@Field1,@Field2,@Field3,@Field4);
END
GO

Aquí está el código de Delphi para invocar este procedimiento almacenado con ADO:

......
var
ADOStoredP: TADOStoredProc;

......
begin

........
ADOStoredP:=TADOStoredProc.Create(nil);
try
ADOStoredP.Connection:=DataMod.SQL_ADOConnection; //Your ADO Connection instance here
ADOStoredP.ProcedureName:="Update_table1";
ADOStoredP.Parameters.CreateParameter("@Field1", ftInteger, pdInput, 0, 0);
ADOStoredP.Parameters.CreateParameter("@Field2", ftInteger, pdInput, 0, 0);
ADOStoredP.Parameters.CreateParameter("@Field3", ftInteger, pdInput, 0, 0);
ADOStoredP.Parameters.CreateParameter("@Field4", ftInteger, pdInput, 0, 0);

While () -- Your text file loop here
begin

ADOStoredP.Parameters.ParamByName("@Field1").Value:=Field1 value from text file here;
ADOStoredP.Parameters.ParamByName("@Field2").Value:=Field2 value from text file here;
ADOStoredP.Parameters.ParamByName("@Field3").Value:=Field3 value from text file here;
ADOStoredP.Parameters.ParamByName("@Field4").Value:=Field4 value from text file here;

ADOStoredP.ExecProc;

end

finally
if Assigned(ADOStoredP) then
begin
ADOStoredP.Free;
end;
end;

........
end;

5 para la respuesta № 2
  1. Si es posible, debe enviar el archivo de texto al servidor que ejecuta SQL Server. Entonces use OPENROWSET (A GRANEL) para abrir el archivo de texto (consulte "E. Uso del proveedor de OPENROWSET BULK con un archivo de formato para recuperar filas de un archivo de texto").
  2. Si no puede enviar el archivo de texto al servidor, cree una tabla de base de datos temporal o persistente y use INSERT para insertar todas las filas de archivos de texto en la tabla.
  3. Si está utilizando SQL Server 2008, entonces debería usar UNIR operador. Si hay una versión más antigua de SQL Server, entonces puede usar dos comandos SQL: ACTUALIZAR e INSERTAR. Y como fuente de datos use (1) OPENROWSET o (2) tabla DB.