2010-02-22 17 views
7

¿Hay alguna forma más rápida para iterar a través de un conjunto de datos de ADO queDelphi ADO consulta

while (not ADOQuery1.Eof) do 
    begin 
     /* Do something */ 
     ADOQuery1.Next; 
    end; 

necesito para escanear un conjunto de datos de alrededor de 9000 artículos y sólo extraer registros que coinciden con un conjunto predefinido de números sucursales.

Respuesta

7

Es mucho más rápido utilizar ADORecordset para estas tareas:

while not ADOQuery1.Recordset.EOF do 
    begin 
    ADOQuery1.Recordset.MoveNext; 
    // get value 
    SomeVar := ADOQuery1.Recordset.Fields['FieldName'].Value; 
    end; 
+1

¿Es eso verdad? Pensé que las llamadas .neof .eof y .fields simplemente irían al objeto del conjunto de registros de todos modos. – MarkF

+0

Tiene razón, pero controlar el conjunto de registros directamente es mucho más rápido, porque el conjunto de datos hace muchas otras cosas que ralentizan la iteración. – Linas

+0

Esto proporcionará un poco de aumento de velocidad, pero probablemente no tanto como no tener que repetir tantos registros en primer lugar. –

8

@Pieter, dos opciones

1) puede modificar su sentencia SQL antes de ejecutar, añadiendo el partido en condición de wich con el conjunto predefinido de números de sucursales.

2) utilizando la propiedad Filter de TAdoQuery.

AdoQuery1.close; 
AdoQuery1.filter := 'your condition goes here'; 
AdoQuery1.filtered := true; 
AdoQuery1.Open; 
+4

Tiene razón. La forma más rápida de lograr esto es usar una cláusula WHERE en el SQL, por lo que solo devuelve los registros que necesita. SQL está específicamente optimizado para hacer esto y es probable que haga un mejor trabajo que cualquier otro que pueda hacer en el lado del cliente. –

+0

Esta respuesta supone que uno * puede * filtrar los datos en el nivel db. Me he encontrado con muchas situaciones en las que el filtrado implica llamadas a un método de aplicación y simplemente no se puede hacer con una cláusula where. –

10

Asegúrese de que utiliza DisableControls/EnableControls si no es NECESARIO para no gastar tiempo en actualizar controles visibles asociados al conjunto de datos.

try 
    ADOQuery1.DisableControls; 
    while (not ADOQuery1.Eof) do 
    begin 
     /* Do something */ 
     ADOQuery1.Next; 
    end; 
finally 
    ADOQuery1.EnableControls; 
end; 

Saludos.

+3

Consulte http://edn.embarcadero.com/article/27790 para saber por qué esto es importante. –

+0

Gracias por el enlace, Gerry. –

0

Se pueden obtener ganancias adicionales en el rendimiento evitando cualquier comparación de cadenas hasta que sea lo más tarde posible (cuando todo lo demás coincide). Si tiene una gran cantidad de cadenas duplicadas en su base de datos, considere ubicarlas en una tabla separada, unida a la primera tabla por un número entero.

-1

es posible que desee cambiar la consulta SQL para incluir una cláusula where, algo así como

Select whatever fields From whatevertable 
where branchnumber in (
    select branchnumber from whatevertable where branchid=xxz 
) 

También sugeriría mirar sólo hacia adelante, cursores de sólo lectura para dar el mayor aumento de la velocidad.

0

Delphi ADO cosas (TADOQuery o TADOTable) no está nada mal, es horrible (verificado con Delphi XE2/2007). Estaba exportando datos de tablas Transbase (controlador ODBC) a MySQL a través de archivos sql y Navicat. Para la tabla con cerca de millones de registros, toma muchas horas hasta ADO (8 millones de registros estaban al 10% después de 2 días), varios minutos usando TQuery (pero puede fallar debido a errores BDE con tablas grandes, BDE no se actualizó el último 15 años), varios minutos a través de ODBC puro o Navicat. Mi consejo: use cualquier cosa en lugar de ADO (al menos hasta que los desarrolladores lo hayan revisado seriamente).

Cuestiones relacionadas