none
Optimizar el llenado de un DataGridView. RRS feed

  • Pregunta

  • Bueno, tengo el siguiente problema:

    Tengo una consulta en SQL que devuelve muchos registros (aproximadamente 10.000), la cual ejecuté en el SQL y me demoró 12 minutos. Ahora bien, tengo una aplicación en C# que me llena un DataGridView con los resultados de esa consulta. Los pasos del llenado son:
    -Utilizo DataReader para obtener los resultados de la consulta.
    -Mapeo los resultados del DataReader a objetos y los voy metiendo en un List<>.
    -Devuelvo el List<> a la capa de interfaz, y asigno al DataSource del DataGridView la lista.

    El problema que tengo es que en mostrarse la grilla completa demoró ¡45 minutos! es decir, 30 minutos más que lo que demora la consulta SQL. ¿Cómo puedo optimizar esto, si es que hay alguna forma?

    Saludos y gracias.

    lunes, 16 de enero de 2012 13:22

Respuestas

  • ¿A qué te referís con "paginando"?

    segmentar la informacion de a grupos de quizas 50 registros y mostrarle las flechas de nevegacion para ir avanzando pagina a pagina por los grupos de registro

    Sé que para el usuario no tiene valor, pero quiere ver esa cantidad de registros, no hay otra. ¿Cómo puedo hacer?

    pero entocnes muestrale un reporte, no en pantallla, cada funcionalida tiene su tecnica, mostrar ese volumen de registros en el grid no es nada saludable para la aplicacion

    si necesitas verlo creales un reporte que esta pensado para esto


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Josecanalla lunes, 16 de enero de 2012 21:13
    lunes, 16 de enero de 2012 14:01

Todas las respuestas

  • una consulta en SQL que devuelve muchos registros (aproximadamente 10.000),

    pues ahi esta el problema, el grid no esta pensado para mostrar ese nuemro de registros

    deberias proporcionar al usuario tecnicas que aporten valor a la aplicacion, ya sea paginado o filtros que permitan limitar el numero de filas que se cargan

    mostrar ese numero de registros no tiene utilidad para una persona porque no puede analziar ese volumen, pero con paginado y filtros de busqueda le dar funcionalidad de analisis

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 13:26
  • ¿A qué te referís con "paginando"?

    Sé que para el usuario no tiene valor, pero quiere ver esa cantidad de registros, no hay otra. ¿Cómo puedo hacer?

    lunes, 16 de enero de 2012 13:54
  • ¿A qué te referís con "paginando"?

    segmentar la informacion de a grupos de quizas 50 registros y mostrarle las flechas de nevegacion para ir avanzando pagina a pagina por los grupos de registro

    Sé que para el usuario no tiene valor, pero quiere ver esa cantidad de registros, no hay otra. ¿Cómo puedo hacer?

    pero entocnes muestrale un reporte, no en pantallla, cada funcionalida tiene su tecnica, mostrar ese volumen de registros en el grid no es nada saludable para la aplicacion

    si necesitas verlo creales un reporte que esta pensado para esto


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    • Marcado como respuesta Josecanalla lunes, 16 de enero de 2012 21:13
    lunes, 16 de enero de 2012 14:01
  • Me interesó la técnica del paginado, ¿hay que hacerlo "a pulmón" o hay alguna forma semi-automatizada de hacerlo?
    lunes, 16 de enero de 2012 14:21
  • y si habria que armarlo, auntomatico no esta esta funcionalidad

    http://social.msdn.microsoft.com/Forums/es/netfxes/thread/d06cba4c-abf0-463e-966e-db5c6354ae89

    http://social.msdn.microsoft.com/Forums/es/winformses/thread/4e49805f-a0c3-4d19-948a-c5bbf23241a6

    se trato el tema en el foro, quizas ayude las respuestas que se dieron

     

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 14:28
  • Hola Jose.

    ¿Te has planteado el uso de un ListView? Es mucho más óptimo y puedes controlar la visualización mucho más a fondo.


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    lunes, 16 de enero de 2012 14:34
  • ¿Te has planteado el uso de un ListView? Es mucho más óptimo

    mucho mas optimo ? estas seguro

    el listview ni siquiera tiene el concepto de filas y columnas, como puede esto controlar la visualizacion si es un control que nunca se penso para trabajar como tabla, solo tiene el cocnepto de items y simula una lsita asignadno del estilo de Details

    es mas ni siquiera tiene un DataSource que asignar, hay que crear los items uno a uno, eso no diria que es optimo

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 14:37
  • Totalmente! 

    Sí que tiene un DataSource y está pensado para mostrar datos http://msdn.microsoft.com/es-es/library/bb398790.aspx

    La velocidad de carga, el peso en datos y la flexibilidad para mostrar los datos lo hacen mejor que las demás opciones http://www.beansoftware.com/ASP.NET-Tutorials/Repeater-DataList-ListView-GridView.aspx

     

    Comparación entre GridView, ListView, DataList y Repeater 

     

    Ejemplo de uso de un ListView http://mredison.wordpress.com/2007/12/27/ejemplo-de-listview-en-aspnet-35/


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    lunes, 16 de enero de 2012 14:50
  • pero es una aplicacion winforms la que aqui se esta evaluando, a que ListView te referias ?

    pense que era el listview de winforms, no el de asp.net, en los links que proporcionas se comparan controles de asp.net


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 15:01
  • Ups, sorry, no me di cuenta de que es en winforms.

    Mea culpa ;o)


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    lunes, 16 de enero de 2012 15:02
  • Jose,

    Deberias evaluar la consulta de SQL, como indices en las tablas y las condiciones (where) en el query al traer los registros, que lo estes haciendo por los indices que tengas.

    Saludos.


    DCE 2005 : 5 Estrellas Platino
    lunes, 16 de enero de 2012 15:13
  • lo que demora no es la query, esta seguro se efectue en segundos, por ams que no use ningun indice o clave

    el problema es la representacion en pantalla, el render, de 10000 en el datagridview, es alli donde se consume todo el tiempo


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 15:22
  •  

    En este artículo de la MSDN se explican algunos pasos a seguir para minimizar el alto coste de la representación de los datos en el DataGridView http://msdn.microsoft.com/en-us/library/ha5xt0d9.aspx

    En este otro artículo se explica cómo mejorar el rendimiento al mostrar gran cantidad de datos http://www.anujvarma.com/superfast-rendering-of-ui-data-in-winforms-world/

    Aún así, tal y como expone Leandro, el problema del rendimiento se produce en la renderización de los datos en el DataGridView


    "En los momentos de crisis, sólo la imaginación es más importante que el conocimiento"
    lunes, 16 de enero de 2012 15:31
  • Leandro, al comienza dice que:

    ....Tengo una consulta en SQL que devuelve muchos registros (aproximadamente 10.000), la cual ejecuté en el SQL y me demoró 12 minutos.....

    Claro lleva mas tiempo la carga donde diste la solucion del paginado, quizas se pueden bajar mas los tiempos revisando la consulta.

    http://es.wikipedia.org/wiki/%C3%8Dndice_%28base_de_datos%29

    Saludos.


    DCE 2005 : 5 Estrellas Platino
    lunes, 16 de enero de 2012 15:31
  • si pero esos 12 min los tomo viendo los registros en el datagridview

    no comento que ejecuto en el sql server management studio y le demoro ese tiempo


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    lunes, 16 de enero de 2012 15:37
  • Yo utilizo SQL server 2005 y he realizado consultas a mas de 10,000 registros y he volcado elr esultado de la consulta a un datagidview y no se tarda tanto tiempo.

    porque en ves de usas datareader y lista, no haces una consulta que devuelva los datos a un datatable y lugo volcas el datatable a tu grilla.

    Ejemplo:

    public Class Obdatos
    {
     public static DataTable GetAllDatos()
            {
                string cConsulta = @"SELECT * FROM Tutabla";            
    using (SqlConnection dbConn = new SqlConnection(Tu cadena de conexion))
                {
                    try
                    {
                        SqlCommand cmd = new SqlCommand(cConsulta,dbConn);
    
                        SqlDataAdapter da = new SqlDataAdapter(cmd);
                        dbConn.Open();
                        da.Fill(dt);
                        dbConn.Close();
                        return dt;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return null;
                    }
                }
            }
            #endregion
    }

    Ahora ya tienes tu datatable solo tienes que llamarla y listao.

    del form, ya sea de un boton o al cargar pones

    tugrid.Datasource=Obdatos.GetallDatos();

     

    Espero te sirva la explicacion.


    • Editado Pcardoza lunes, 16 de enero de 2012 17:09
    lunes, 16 de enero de 2012 17:08
  • Vamos a ver que hay un desorden que no entiendo, lo primero es que el problema esta en el punto de como dice @Leandro

    "Esto no se resuelve con un DataTable(malos que son), ni con un indice y con ninguna historias de estas", este problema se resuelve sentandose a pensar, en que, como pretendes tu en un ser humano evalue 10,000 registros?

    Hay es que esta el problema, un usuario quiere 10,000 para ver un reporte por ejemplo de Ventas Anuales de un producto, pero no para verlas una por una en un Grid, eso es ilogico, esto no es como dije problema de indices ni de nada es de Logica humana llana y pura.

    Cuando se desarrolla aplicaciones en lenguajes orientados a objetos no podemos pretender nunca llevar la vida real al codigo, siempre es al revez, llevar el codigo a la vida real, por ejemplo: soy un analista de ventas, pasa el año se supone que mi trabajo es anualmente revisar las  ventas anuales como mencione anteriormente, al menos y ni siquiera asi que sea que yo tenga que revisar factura por factura y en el grid cotejar una columna que diga verificada, por poner asi un ejemplo, para que querria yo tener 10,000 filas en un grid, eso es absurdo, y si fuera ese el caso, me hiciera un proceso interno de la aplicacion para realizar esta tarea, pero bueno como dice nuestro amigo @Josecanalla que es el usuario que lo quiere, hay que ponerse manos a la obra con esto

    Te recomiendo jose que sigas los consejos de @Leandro en este caso de Paginacion te sera muy util, me he encontrado este linq del Guille que es muy bueno Paginacion Eficiente en Sql Server

    Saludos




    Luis Y. Ramirez "Recuerda marcar la repuesta como VALIDA si te ha ayudado"
    • Propuesto como respuesta Víctor E. Díaz miércoles, 7 de noviembre de 2012 17:32
    lunes, 16 de enero de 2012 17:38
  • Optimizé la consulta en SQL desnormalizando una tabla, y ahora la cosa funciona mejor. Me lo carga rápido el DataGridView... muchas gracias a todos por los consejos, marco como respuesta la primera pero en realidad todas fueron útiles. Saludos.
    lunes, 16 de enero de 2012 21:13
  • Yo utilizo SQL server 2005 y he realizado consultas a mas de 10,000 registros y he volcado elr esultado de la consulta a un datagidview y no se tarda tanto tiempo.

    porque en ves de usas datareader y lista, no haces una consulta que devuelva los datos a un datatable y lugo volcas el datatable a tu grilla.

    Ejemplo:

    public Class Obdatos
    {
     public static DataTable GetAllDatos()
            {
                string cConsulta = @"SELECT * FROM Tutabla";            
    using (SqlConnection dbConn = new SqlConnection(Tu cadena de conexion))
                {
                    try
                    {
                        SqlCommand cmd = new SqlCommand(cConsulta,dbConn);
    
                        SqlDataAdapter da = new SqlDataAdapter(cmd);
                        dbConn.Open();
                        da.Fill(dt);
                        dbConn.Close();
                        return dt;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return null;
                    }
                }
            }
            #endregion
    }

    Ahora ya tienes tu datatable solo tienes que llamarla y listao.

    del form, ya sea de un boton o al cargar pones

    tugrid.Datasource=Obdatos.GetallDatos();

     

    Espero te sirva la explicacion.


    Hola, he visto que la pregunta está resuelta, pero esta frase tuya me llega a esa parte mía que mas me duele :).

    porque en ves de usas datareader y lista, no haces una consulta que devuelva los datos a un datatable y lugo volcas el datatable a tu grilla.

    Eso que propones es más ineficaz que lo otro como 20 veces o como decir 200 :)

    Saludos,


    phurtado
    lunes, 16 de enero de 2012 21:30
    Moderador