FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
Un Insert muy lento.........
Estoy trabajando en los reportes de una aplicación y opté por usar un procedimiento para generar una tabla local temporal (BDE) para almacenar las lineas del reporte y luego generar la salida usando un TQuickRep.
Todo funciona razonablemente bien pero el rendimiento es patetico, haciendo diversas pruebas logre detectar que si quito la linea de "ExecSQL" que corresponde al insert de los datos en la tabla temporal el rendimiento cambia drasticamente (desgraciadamente no se genera el reporte ) pero agregar unos 400 registros en el archivo temporal toma hasta 20seg (si quito la linea "ExecSQL" todo el proceso dura menos de 1 seg) por lo que asumo que mi problema de rendimiento está directamente asociado al insert Este es el código: (fDataMod.Q1 es un tQuery conectado a un TDatabase local).
¿ El uso de Parametros afecta (mucho) el rendimiento ? ¿ Que puedo hacer para acelerar el proceso de inserción ? Gracias
__________________
Sitrico Última edición por sitrico fecha: 26-05-2005 a las 23:34:23. |
#2
|
||||
|
||||
Curiosa manera de generar un reporte. ¿Por qué en lugar de crear una tabla temporal no simplemente haces una consulta SELECT de los datos que necesites y con ella alimentas al QuickReport?
// Saludos |
#3
|
||||
|
||||
Sabia que me iban a preguntar por eso,
La razón principal para generar el temporal es que entre otras características de la aplicación me pidieron que fuera capaz de generar los reporte tanto en impresoras de tinta y laser como en matriz de puntos (en formato plano) y la solución que encontré fue precisamente llenar un archivo temporal con los datos del reporte y luego llamar a un tQuickRep para la salida "Windows" y/o a un procedimiento para la la salida en Matriz de Puntos. También debo aclarar que la mayoria de los reportes son bastante complejos (no son presisamente un simple listado de una o varias tablas) incluyen un monton de líneas adicionales que no están en la tabla, totales por nivel de grupo y otras cosas raras. Por eso preferí pre-procesar el reporte y después generarlo, y también (aunque parezca mentira) porque me permite usar un código más consistente a la hora de administrar los QuickRep (Solo uso una clase base que heredo para la salida) creando los campos de reporte desde el código en tiempo de ejecución. Pero, en el fondo tienes razón, normalmente es más fácil generar una consulta e imprimirla directamente.
__________________
Sitrico |
#4
|
|||
|
|||
No indicas que tipo de tabla es, pero si es paradox o dbase, es infinitamente mas rapido usar un TTable y asignar los campos directamente.
Otra problema con esa query es que la estas limpiando y recreando continuamente (el Sql.Clear y Sql.Add) por cada registro, esto obliga al engine a parsear la sentencia cientos de veces, lo que aumenta tambien la lentitud, deberias asignar una sola vez la sentencia sql al principio, y despues simplemente solo asignar los parametros en el bucle. La forma mas rapida es algo como esto: Código:
// Tabla es un objeto TTable , creado previamente y con los campos // añadidos en tiempo de diseño: Click boton derecho // sobre el objeto TTAble -> Edit Fields -> Add Fields Tabla.Append; TablaCodMay.AsString := Datos.CMay; TablaCodAux.AsString := Datos.CAux; TablaDescrip.AsString := Datos.Desc; TablaRef.AsString := Datos.Ref; ... ... Tabla.Post; Código:
Tabla.Append; Tabla.FieldByName('CodMay').AsString := Datos.CMay; Tabla.FieldByName('CodAux').AsString := Datos.CAux; Tabla.FieldByName('Descrip').AsString := Datos.Desc; Tabla.FieldByName('Ref').AsString := Datos.Ref; ... ... Tabla.Post; Saludos |
#5
|
||||
|
||||
Para no cambiar mucho la estructura que ya tenes definida, podes valerte de tun TClientDataset o un TrxMemoryData, definir su estructura en tiempo de diseño y luego valerte de los métodos Insert/Post para rellenarlo. Esto no debiera añadir mas que algunos milisegundos a la operación de tu programa, pues todo se hará en memoria.
hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#6
|
||||
|
||||
Gracias Roman, Mick y jachguate, voy a crear un tRXMemoryData (que es en en escencia un TTable) y lo manejo todo desde memoria. Ahora el asunto es donde crear el objeto, creo que lo voy a asociar directamente a mi reporte Base (el Dataset del reporte será un tRXMemoryData) y aplicaré las inclusiones directo a él.
Otra cosa ¿ Hay alguna diferencia entre tTable.Append y tTable.Insert ?. Yo siempre he usado el insert, pero la verdad no veo diferencias reales. // Primeros resultados Cita:
__________________
Sitrico |
#7
|
||||
|
||||
Bueno, con el RxMemoryData el rendimiento es optimo (< 1 seg) para generar los temporales y al usar directamente la tabla del reporte también me permitio eliminar algo de código
El problema (generalmente hay uno) es que los reportes me los muestra en orden inverso y no encuentro la manera de indexar ó ordenar el RxMemoryData. ¿ Alguien sabe como ? Gracias
__________________
Sitrico |
#8
|
||||
|
||||
Cita:
// Saludos |
#9
|
||||
|
||||
No tiene propiedad IndexFieldNames?
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate |
#10
|
||||
|
||||
Bueno, y sólo para futura referencia, el RxMemoryData no tiene (hasta donde sé) capacidad para ordenar o indexar archivos (mejor dicho estructuras de datos) la solución que encontre fue sustituir el "Insert" por un "Append".
Aparentemente y respondiendo mi pregunta anterior Cita:
En cuanto al rendimiento ahora mis reportes se generan en 1 seg. Gracias a todos.
__________________
Sitrico |
|
|
|