Grandes cantidades de datos

14/04/2007 - 03:24 por SoftMedia | Informe spam
Hola a todos,
Estoy desarrollando una aplicación en Winform y una de las cosas que hace es
cargar unos datatable desde unos archivos de texto plano mediante un parser
de texto que me he fabricado, estos archivos cada semana tienen más registros
(ya van por alrededor de 1.000.000). Estos datatables los hago que se cargen
en la base de datos (SQL Server 2005 SE) como una transacción en bloque de
con la siguiente función:

Public Function cargar_tablas(ByVal dt() As DataTable) As Boolean
Dim qs(4) As String
qs(0) = "SELECT * FROM ASUNTOS"
qs(1) = "SELECT * FROM CONTRATOS"
qs(2) = "SELECT * FROM TITULARES"
qs(3) = "SELECT * FROM MOVIMIENTOS"
qs(4) = "SELECT * FROM INTERVINIENTES"

conexion.Open()

Dim trans As SqlTransaction = conexion.BeginTransaction

Try

Dim da0 As New SqlDataAdapter()
Dim cb0 As SqlCommandBuilder = New SqlCommandBuilder(da0)
da0.SelectCommand = New SqlCommand(qs(0), conexion)
da0.SelectCommand.Transaction = trans
da0.Fill(dt(0))
da0.Update(dt(0))

Dim da1 As New SqlDataAdapter()
Dim cb1 As SqlCommandBuilder = New SqlCommandBuilder(da1)
da1.SelectCommand = New SqlCommand(qs(1), conexion)
da1.SelectCommand.Transaction = trans
da1.Fill(dt(1))
da1.Update(dt(1))

Dim da2 As New SqlDataAdapter()
Dim cb2 As SqlCommandBuilder = New SqlCommandBuilder(da2)
da2.SelectCommand = New SqlCommand(qs(2), conexion)
da2.SelectCommand.Transaction = trans
da2.Fill(dt(2))
da2.Update(dt(2))

Dim da3 As New SqlDataAdapter()
Dim cb3 As SqlCommandBuilder = New SqlCommandBuilder(da3)
da3.SelectCommand = New SqlCommand(qs(3), conexion)
da3.SelectCommand.Transaction = trans
da3.Fill(dt(3))
da3.Update(dt(3))

Dim da4 As New SqlDataAdapter()
Dim cb4 As SqlCommandBuilder = New SqlCommandBuilder(da4)
da4.SelectCommand = New SqlCommand(qs(4), conexion)
da4.SelectCommand.Transaction = trans
da4.Fill(dt(4))
da4.Update(dt(4))


trans.Commit()
Catch ex As Exception
trans.Rollback()
conexion.Close()
Return False
End Try
conexion.Close()
Return True
End Function

Hasta aquí todo bien, trada en hacerlo, pero no importa demasiado porque
solo se hace una vez por semana, pero si supierais una mejor manera, mejor.
El problema gordo está en que cuando cargo una de las tablas con muchísimos
registros en un dataset y lo visualizo en un datagridview la operación puede
tardar más de 2 minutos y esto no se puede permitir porque eso si es una
práctica habitual y crítica. Yo solo he trabajado con datasets y pocos
registros y esto se me hace un poco cuesta arriba, ¿Hay alguna manera mejor
para optimizar la carga de este datagridview y en general para tratar con
estas grandes cantidades de registros?
Muchas gracias de antemano.
Un saludo.

Preguntas similare

Leer las respuestas

#6 SoftMedia
15/04/2007 - 01:52 | Informe spam
Hola de nuevo.

La verdad es que a mi tampoco me gusta nada el crystalreport, me dio mucho
la lata el dia que tuve que distribuirlo y veo que es muy lento con la
captura de datos, pero tal vez es que no lo hago bien.

¿No hay otra apliación (aparte de reporting services) para hacer estos temas
de tratamiento de documentos e impresión que funcione con vs 2005?

Creo que el mayor problema de la lentitud es la siguiente: En el reporte hay
datos que se cogen de varios procedimientos almacenados, éstos a su vez
captan los datos de distintas tablas. Es muy posible que no esté actuando
correctamente con esto. Supongo que deberé hacer una consulta de múltiples
tablas con inner join y eso para simplificar la toma de datos, ¿no?

Pero si conoces otra aplicación te agradecería que me lo dijeras.

Muchísimas garcias por todo.

Un saludo.



"Alberto Poblacion" wrote:

"SoftMedia" wrote in message
news:
> [...] utilizo un
> crystalreportsviewer, pero me tarda una barbaridad en mostrar la
> información
> en el reporte. ¿Sabes si hay algo para hacer esto más rápido?

La verdad es que le tengo un poco de manía al Crystal Reports, por la
cantidad de problemas que da para conseguir que funcione como quieres y para
distribuir las aplicaciones y conseguir que se instale correctamente, Asi
que procuro evitar usarlo siempre que puedo. Por ejemplo, para listados
sencillos a veces prefiero usar un PrintDocument y dibujar la página con
GDI+.

Pero en fín, si no tienes más remedio que usarlo comprueba una cosa:
cerciórate de que la ficha que estás imprimiendo la sacas con un
SELECT...WHERE... y en el where especificas el registro que quieres. No
configures el Cystal para que envíe el SELECT sin condiciones, indicándole
luego en los filtros la ficha que quieres, porque entonces se trae desde la
base de datos el millón de registros y luego los examina uno a uno buscando
el que quieres imprimir. Obviamente, esto es lento.
Si la sentencia la tienes bien puesta con el WHERE, pruébala a mano en
Sql Server a ver cuánto tarda. Si es lenta, la causa probable es que no
tienes indexado el campo o campos especificados en el Where. Y si están
indexados y sigue siendo lento, entonces te falta ejecutar un "update
statistics".


Respuesta Responder a este mensaje
#7 Alberto Poblacion
15/04/2007 - 08:41 | Informe spam
"SoftMedia" wrote in message
news:
Creo que el mayor problema de la lentitud es la siguiente: En el reporte
hay
datos que se cogen de varios procedimientos almacenados, éstos a su vez
captan los datos de distintas tablas. Es muy posible que no esté actuando
correctamente con esto. Supongo que deberé hacer una consulta de múltiples
tablas con inner join y eso para simplificar la toma de datos, ¿no?

Pero si conoces otra aplicación te agradecería que me lo dijeras.



Alguna vez he utilizado el Component One, pero era para un cliente que
ya tenía la licencia de la suite completa. Funcionaba bastante bien, pero no
sé si vale la pena comprarlo solo para imprimir una simple ficha.

En cuanto al tema de lentitud, una forma de comprobar si el problema está
en los accesos a base de datos consiste en usar el Sql Profiler. Arrancas el
Profiler en el servidor y lanzas el listado. Cuando el listado termina, vas
al Profiler y compruebas cuánto han tardado en ejecutarse las sentencias
Sql. Si el tiempo que tarda en salir el listado es casi igual al que han
tardado en ejecutarse las sentencias, entonces no vas a conseguir ganar nada
cambiando la herramienta cliente que emite el listado. En este caso, la
única solución pasa por optimizar las consultas que se están enviando al
servidor (por ejemplo, como tú dices, haciendo un join bien hecho y
añadiendo los índices adecuados a las tablas).
Respuesta Responder a este mensaje
#8 Alberto Poblacion
15/04/2007 - 08:44 | Informe spam
"SoftMedia" wrote in message
news:
Si ya tengo los datos de las cinco
tabla sacadas de los archivos de texto en sendos datatables, ¿como hago
para
subirlas al servidor de sql server?



Si ya tienes los datos en datatables, súbelos como estás haciendo hasta
ahora (con un dataadapter) pero ponle al dataadapter en la propiedad
UpdateBatchSize un valor grande (por ejemplo, 100) para que envíe los
registros al servidor de 100 en 100 en lugar de enviarlos de 1 en 1.
Respuesta Responder a este mensaje
#9 SoftMedia
15/04/2007 - 19:24 | Informe spam
¿Hasta cuantos registros aguantan los datatables? Ten en cuenta que estamos
hablando de millones de registros y creciendo...

Con respecto a lo que me dices en los anteriores posts del asunto de
crystalreports me ha llamado la atención lo de los printdocuments y gdi+, es
posible que sea la solución a mis "penas" ya que los reports no son
excesivamente complejos. ¿Serías tan amable de explicarme un poco mejor como
se haría esto? No obstante voy a intentar optimizar las consultas tal como me
dices.

Te agradezco mucho todas las molestias que te estás tomando para ayudarme.

Un cordial saludo.

"Alberto Poblacion" wrote:

"SoftMedia" wrote in message
news:
> Si ya tengo los datos de las cinco
> tabla sacadas de los archivos de texto en sendos datatables, ¿como hago
> para
> subirlas al servidor de sql server?

Si ya tienes los datos en datatables, súbelos como estás haciendo hasta
ahora (con un dataadapter) pero ponle al dataadapter en la propiedad
UpdateBatchSize un valor grande (por ejemplo, 100) para que envíe los
registros al servidor de 100 en 100 en lugar de enviarlos de 1 en 1.


Respuesta Responder a este mensaje
#10 Alberto Poblacion
15/04/2007 - 20:30 | Informe spam
"SoftMedia" wrote in message
news:
¿Hasta cuantos registros aguantan los datatables? Ten en cuenta que
estamos
hablando de millones de registros y creciendo...



El límite de registros del datatable viene impuesto por el hecho de que
todos ellos se cargan en memoria simultaneamente. Por ejemplo, si tienes 1
Gigabyte de memoria virtual disponible para tu programa, y cada registro
mide 2000 bytes (en el formato interno en que los guarde el datatable, por
ejemplo, los strings son Unicode y por tanto gastan 2 bytes por carácter),
pues entonces te cabría algo menos de medio millón de registros.

Desde luego, si estamos hablando de millones de registros, no es nada
recomendable almacenarlos en un datatable. Conviene modificar el proceso
para que los vaya salvando a la vez que los lee, para no tener que cargarlos
todos a la vez en memoria.


Con respecto a lo que me dices en los anteriores posts del asunto de
crystalreports me ha llamado la atención lo de los printdocuments y gdi+,
es
posible que sea la solución a mis "penas" ya que los reports no son
excesivamente complejos. ¿Serías tan amable de explicarme un poco mejor
como
se haría esto? No obstante voy a intentar optimizar las consultas tal como
me
dices.



El PrintDocument es un Control que tiene un método llamado Print. Cuando
lo llamas, dispara un evento llamado PrintPage, al cual le llega dentro del
EventArgs un objeto de tipo Graphics. Con ese Graphics, se van ejecutando
los métodos de dibujo de GDI+, de forma que vas haciendo DrawLine,
DrawString, etc, para dibujar la página tal como quieras que salga impresa.
Si hay más páginas, devuelves e.HasMorePages=True, y se vuelve a disparar el
evento para que dibujes la siguiente página. El PrintDocument tiene varias
propiedades para seleccionar la impresora, la configuración de la página,
etc., y también tiene la previsualización en pantalla del documento antes de
mandarlo a impresora.
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida