4 votes

Problèmes de performance lors du chargement d'un grand ensemble de données dans un GridView c#

Ok,

J'ai testé des ensembles de données relativement petits dans mon GridView, et tout a bien fonctionné. Cependant, je suis maintenant passé à l'UAT proprement dit et j'ai essayé de charger 17 000 enregistrements dans ma grille, ce qui a pratiquement mis mon application web à l'arrêt.

En gros, un utilisateur se connecte et, après validation, toutes les grilles de données sont chargées, dont l'une contient 17 000 enregistrements. Jusqu'à ce que tout soit chargé, l'utilisateur final reste sur la page de connexion. J'ai donc besoin de réparer cela.

Le code pour les grilles est :

DataTable dtValueDateCurrency = null;               
SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["Reporting"].ConnectionString);
using (conn)
{
    conn.Open();
    //Load all other grid data
    using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(TSQL1, conn))
    {
        dtValueDateSummary = new DataTable();
        sqlAdapter.Fill(dtValueDateSummary);
        grdValueDateSummary.DataSource = dtValueDateSummary;
        grdValueDateSummary.DataBind();
    }
 }

Y a-t-il un moyen d'augmenter les temps de chargement ? La pagination n'est pas une option, car je m'en occupe avec JQuery.

6voto

Chase Florell Points 18248

Le chargement de 17 000 enregistrements en une seule requête est ce qui vous tue. Je suggère fortement de paginer votre grille.

Vous devez d'abord modifier votre procédure stockée comme suit.

ALTER PROCEDURE [dbo].[SomeTable_GetPagedResults] 
( 
        @StartRowIndex      int, 
        @MaximumRows        int 
) 

AS 
SET NOCOUNT ON 

Select 
    RowNum, 
    [ID], 
    [foo],
    [bar]
From 
    (Select 
        [ID], 
        [foo], 
        [bar], 
        Row_Number() Over(Order By [ID] Desc) As RowNum 
        From dbo.[SomeTable] t) 
As DerivedTableName 
Where RowNum Between @StartRowIndex And (@StartRowIndex + @MaximumRows) 

Vous avez maintenant une requête qui peut être mise en page.

Vous voulez aussi une requête pour obtenir le nombre complet de lignes.

ALTER PROCEDURE [dbo].[SomeTable_GetRowCount] 

AS 
SET NOCOUNT ON 

return (Select Count(ID) As TotalRecords From SomeTable) 

Vous liez votre grille à chaque fois que vous changez de page.

protected void gridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
  gridView1.PageIndex = e.NewPageIndex;
  BindGrid(); // this is whatever method you call to bind your data and execute your stored procedure.
}

Et le BindGrid() appellera vos deux procédures stockées (l'une pour obtenir le nombre complet de lignes et l'autre pour obtenir les résultats relatifs à la page actuelle).

Lectures complémentaires

2voto

Garrison Neely Points 2370

Vous devez instaurer la pagination de la base de données.

Cela implique la création d'un tri personnalisé, d'un filtrage personnalisé et d'une pagination personnalisée, mais cela augmentera considérablement les performances de votre code, car vous ne récupérerez qu'une page de données à la fois dans la base de données, au lieu des 17 000 lignes à la fois.

Je l'ai mis en œuvre dans une application bancaire conçue pour afficher, trier et filtrer des centaines de milliers de prêts. La réponse est trop compliquée pour donner un exemple simple, mais commencez par étudier la pagination des bases de données. Utilisez LINQ, qui vous donnera des résultats simples. Take y Skip pour mettre en œuvre la pagination la plus simple.

1voto

Jesse Smith Points 953

Vous devriez envisager de mettre en cache la requête sur le serveur Web, surtout si elle est rarement mise à jour. De cette façon, tous les clients peuvent simplement surfer sur le cache au lieu de frapper impitoyablement la base de données.

Ver cette question SO

0voto

NeverHopeless Points 3962

Vraiment, charger un enregistrement de 17k une fois n'est pas utile, même si l'utilisateur ne peut pas voir l'ensemble des 17k enregistrements à la fois. Je vous suggère d'utiliser la pagination en plus de DataTable.Merge qui permet de charger les enregistrements par morceaux et d'ajouter les nouvelles données extraites aux précédentes. Je viens de faire un test rapide et j'ai trouvé une solution. Essayez ceci.

-1voto

Furqan 695 Points 3

Il n'y a pas de solution : la pagination est lente et appelle la base de données encore et encore, Vous devez donc mettre

<style>.body{display:none;}</style>

début de la page et à la fin de la page

<style>.body{display:block;}</style>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X