Published: 28 Sep 2009
By: Akhtar Shiekh
Download Sample Code

In this article I am going to demonstrate what are the performance drawbacks of using conventional way to page and sort your GridView and then I will demonstrate 'An Optimized way to implement Paging and Sorting'.

Contents [hide]

Introduction

Paging and sorting are most commonly used features of ASP.NET GridView. And it is very easy to use/implement these features in GridView with small chunk of lines. In this article I am going to demonstrate what are the performance drawbacks of using conventional way to page and sort your GridView and then I will demonstrate 'An Optimized way to implement Paging and Sorting'.

What are conventional steps for Paging and Sorting?

Usually we perform the following steps to enable paging and sorting in our GridView.

1. Set AllowPaging and AllowSorting Properties of GridView to True to enable paging and sorting respectively e.g

2. Set the PageSize property to mention how many records will be display on each page.

3. Set the SortExpression property of each column. By default each Data Bound columns has the bounded column name as default value for the SortExpression property.

4. Handle PageIndexChanging and Sorting Events of GridView to respond to paging and sorting actions respectively, like so:

5. Put some logic in the event handlers to do their jobs

5a. In the PageIndexChanging Event Handler method, we usually get the data from database or somewhere from the Cache and rebind our Grid with that data. After rebinding we change the PageIndex property of the GridView to a new page index to display the page that was selected by the user.

5b. In the Sorting event handler method, we get the sorted data according to the sort expression from our data source (data source could be database/cache/session etc) and then rebind the Grid to display the sorted records.

And that's it.

Drawbacks

In conventional way of paging and sorting we get complete set of data instead of getting only the portion of data that is required to display on current/requested page. As you can see on each pageIndexChanging call we are getting all the data from our data source and then binding it to the GridView. Ideally we should get only the data that we need to display on the requested page.

Hmmm...Sounds good but HOW??

The question that may arise in your mind could be "It seems good in theory that we should only get the required data, but practically if we bind only one page of data with GridView then it would assume that this is the only data that it needs to display. So how does the GridView even display page numbers and total records count? It is a genuine question, so let's try to answer!

An Optimized Way to implement Paging and Sorting

As in the start of this article, we discuss the conventional 5 steps to implement paging and sorting in ASP.NET GridView . In this solution we will use the first 3 steps as described above, and perform the 4th and 5th steps by ourselves. We will use an ObjectDataSource that will perform these steps for us in an optimized way.

High Level Overview

We will optimize the code on both Database and Presentation layers.

At the Database Level we will write a stored procedure in such a way that it would return only one page of records. The stored procedure takes the page size, page index and a sort expression as input parameters and returns sorted records for a particular page index.

At the Presentation layer, we will use ObjectDataSource’s virtual paging feature to optimize the paging. Virtual paging is not a term defined by Microsoft. I used it by myself because ObjectDataSource exposes some properties and methods that allow us to bind only one page of data with GridView and to define the total number of records in database (not in one page), so that the GridView can extract out the total number of pages that need to be display in the page area of the GridView. In the next sections we will see what these properties and methods are, and how to use them.

If you are not familiar with ObjectDataSource then you should first read some articles on that. Here are some articles:

Implementation Details

Database Layer

We have an employee table in a database with the following schema:

And we wrote the following stored procedure that has two select statements. The first select statement will return the total number of employees in the Employee table and the second dynamic select statement will return the sorted records for one page according to the provided start index, page size, and sortby parameters.

One thing that I want to explain in the above stored procedure is the ROW_NUMBER() function that makes it possible for us to select only one page of data. The ROW_NUMBER() method is included in the 2005 release of TSQL. It actually adds an integer column in the selected record set, that contains the record number for each record . It seems very simple but in fact it's very helpful as we are going to perform nested quires. As we did in our stored procedure, in the nested query we select all employees records sorted by the provided sort expression, and add a row number for each record using the ROW_NUMBER() method. In the outer query we filter the result rows by using lower and upper bound indexes so that we return only the rows between lower and upper bounds.

Data Access layer

In the Data Access Layer we will write a class that will be responsible to call the spGetAllEmployee sorted procedure to get employee records and return the employee list to the business logic layer. To avoid increasing the complexity and length of the article I am only posting the code that is used to fetch the records from the database. I am not posting any helper code/classes; however the complete code is available for download.

One thing you might notice is that the last parameter totalEmployee of GetAllEmployee is passed by reference. It is an optimization; we don't want to perform two separate database calls to get employees records and total count. For the same reason we are returning both employee data and total count from a single stored procedure. In the presentation layer it will be clearer to you why this approach is necessary and how it will help us.

Business Logic Layer

Business logic layer will only be calling the Data Access Layer code to fetch the records. Source code is available to download.

Presentation Layer

As we discussed earlier in the article, we will use the virtual paging feature of ObjectDataSource. Object Data Source exposes some interesting properties which are used for virtual paging purposes. To benefit from these properties you should set the EnablePaging property of ObjectDataSource to True. These properties are

  • StartRowIndexParameterName: Specifies the parameter name of the Select method of ObjectDataSource’s bounded Type. ObjectDataSource will pass the value to this parameter when the user changes the page index. For example, if Grid View page size is 10 and the user clicks page number 3 to view the 3rd page, then the ObjectDataSource will calculate the value of StartRowIndexParameter by using the (page Size * page Index) formula. In this case it will be 10 * 3= 30. Default value of this property is startRowIndex, which means that if we don't mention any value for this property then the Select method should have the startRowIndex parameter.
  • MaximumRowsParameterName: Specifies the parameter name of the Select method of ObjectDataSurce’s bounded Type. ObjectDataSource will pass the value to this parameter when the user changes the page Index. ObjectDataSource source gets its value from GridView's PageSize property. Default value of this property is maximumRow, which means that if we don't set any value for this property then the Select method should have the maximumRow parameter.
  • SelectCountMethod: Specifies the method name of ObjectDataSource’s Type. This method will be called by ObjectDataSource to get the total number of records in the database. This count will help ObjectDataSource to create virtual paging in the Grid. For example, if GridView page size is 10, and SelectCountMethod returns 100 as total number of employees in the database then ObjectDataSource will display 10 page indexes in the GridView's pager area, even if we didn't get all the 100 records from the database.
  • SortParameterName: Specifies the parameter name of the Select method of ObjectDataSource’s bounded Type. ObjectDataSource will pass the value to this parameter when the user clicks on any column header to sort the data according to that column. ObjectDataSource fetches the value from the SortExpression property of the particular GridView column.

Now if you see all these three properties together then you will understand that SelectCountMethod will use them to display virtual page indexes in the GridView, and that on each page index change it will use the values of StartRowIndexParameterName and MaximumRowsParameterName parameters to query the database and fetch only the desired page of data.

We have already written stored procedures, data access and business logic code that accepts these parameters and returns only the sorted page of data. So it's time to pass values to these parameters.

Enough theory; now let's write something in C# and ASP.NET.

Listing 1: ASPX: Markup of GridView and ObjectDataSource

Listing 2: EmployeeData.cs: A class which is bound to ObjectDataSource

Nothing special here to explain because we are calling the already explained code to get one page of sorted data by passing the ObjectDataSource provided values. One thing that I want to explain from an optimization point of view is that we are getting employeesCount in the GetAllEmployees() method, and in GetTotalEmployeesCount() we only return that value, instead of fetching the count from database. What people usually do is making separate database calls to fetch the count, which is an unnecessary step because we can write our stored procedure, data access and business logic layer so that we can get the actual data and the total count in a single database call.

Comparison

I've made a comparison between the conventional and the optimized implementation of paging and sorting and there is a HUGE difference between them.

One noticeable thing from this performance table is that as we are increasing the amount of data, the conventional implementation is taking more time to fetch the records from the database, while there is no noticeable difference in the optimized way.

Table 1: Paging Performance

No. of Records

Optimized Paging (in seconds)

Un-optimized Paging  (in seconds)

500000

0.21

07.41

1000000

0.28

17.27

2000000

0.32

36.28

3000000

0.33

54.03

Table 2: Sorting Performance

No. of Records

Optimized Sorting (in seconds)

Un-optimized Sorting  (in seconds)

500000

01.61

10.14

1000000

03.13

23.22

2000000

09:38

47.39

3000000

13.12

70:25

  • The Paging time is calculated on GridView page index changed event.
  • The Sorting time is calculated on GridView sorting event.

Summary

In this article we learned an end to end solution to optimized paging and sorting in ASP.NET GridView. In the Database Layer we used the ROWNUMBER() method which helps us to select only one page of data. And in the Presentation layer we used ObjectDataSource's virtual paging feature by using the StartRowIndexParameterName, MaximumRowsParameterName and SelectCountMethod,SortParameterName parameters.

Feedback

You feedback will really help me to be better, so please leave your comments and suggestions. You can also send me any query at akhhttar at gmail dot com.

Happy Programming!

<<  Previous Article Continue reading and see our next or previous articles

About Akhtar Shiekh

I am Microsoft Certified Technology Specialist for Web Application Development. I have 4 year experience of Web and Distributed application development.I have considerable experience developing client / server software for major corporate clients using the Windows operating systems and .NET platform...

This author has published 2 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Custom GridView with Paging and Filtering
A custom control derived from the GridView that implements filtering, custom Top pager and custom Bo...
Sorting a Gridview with multiple Columns
The Gridview is the most used control to display data in a tabular format. By default it supports ma...
Persisting Selection in ASP.NET Grid Controls While Paging
How to persist selection correctly in a grid control (DataGrid, GridView, and ListView controls) whe...
A first look at the Dynamic Data Engine—the DynamicGridView Control
Dino Esposito introduces the ASP.NET DynamicGridView Control.

You might also be interested in the following related blog posts


VS 2010 Code Intellisense Improvements (VS 2010 and .NET 4.0 Series) read more
Gaia Ajax 3.6 Beta Released! Free download of new Ajax GridView, 35++ Ajax Components and 100++ New Samples read more
Optimized Paging and Sorting in ASP.NET GridView read more
Multiple child views with RadGridView for WinForms read more
WPF Release History : Q1 2009 SP2 (version 2009.1.526) read more
Silverlight Release History : Q1 2009 SP2 (version 2009.1.526) read more
Silverlight Release History : Q1 2009 SP1 (version 2009.1.413) read more
WPF Release History : Q1 2009 SP1 (version 2009.1.413) read more
Improved ASPxGridView Exporting for 2008 vol 2 read more
C# GridView Sorting/Paging w/o a DataSourceControl DataSource read more
Top
 
 
 

Discussion


Subject Author Date
placeholder Well done Muhammad Tariq 9/29/2009 8:48 AM
RE: Well done Akhtar Shiekh 9/29/2009 9:41 AM
placeholder Interesting Article Wassim Brinsi 10/27/2009 10:24 AM
Sorting Armando Alfaro 11/12/2009 6:56 AM
placeholder RE: Sorting Akhtar Shiekh 11/12/2009 7:14 AM
RE: RE: Sorting Armando Alfaro 11/12/2009 8:25 AM
placeholder RE: RE: RE: Sorting Armando Alfaro 11/12/2009 8:28 AM
RE: RE: RE: Sorting unfimliar Akhtar Shiekh 11/13/2009 8:06 AM
placeholder very nice article Hw Lau 11/13/2009 4:03 AM
RE: very nice article Akhtar Shiekh 11/13/2009 8:17 AM
placeholder Amazing Article Sumit Thapar 11/13/2009 6:49 AM
MY BAD...I just replied on wrong comments. Akhtar Shiekh 11/13/2009 8:22 AM
placeholder RE: MY BAD...I just replied on wrong comments. Sonu Kapoor 11/13/2009 10:29 AM
RE: RE: MY BAD...I just replied on wrong comments. Akhtar Shiekh 11/13/2009 11:16 AM
placeholder RE: RE: RE: MY BAD...I just replied on wrong comments. Sonu Kapoor 11/14/2009 2:19 PM
Excellent, but ... Yang Du 12/15/2009 10:17 AM
placeholder Nice Article but Correction needs to be done Bhagwat Phartyal 10/2/2010 6:53 PM
Question about the Sorting Evan Larsen 12/13/2010 12:52 PM
placeholder Nice Article Prasad Ak 3/6/2012 12:07 AM

Please login to rate or to leave a comment.

Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.