5

I have a large amount of data (a sql query with 20000 records) and filling my datagrid with that amount of data takes like 10 minutes, this is my gridview definition:

<asp:GridView ID="g" runat="server" Height="113px" Width="817px" 
BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" 
CellPadding="3" GridLines="Vertical" AllowPaging="True" Font-Size="Small" 
     PageSize="30">
    <AlternatingRowStyle BackColor="#DCDCDC" />
    <FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
    <HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
    <PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
    <RowStyle BackColor="#EEEEEE" ForeColor="Black" />
    <SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
    <SortedAscendingCellStyle BackColor="#F1F1F1" />
    <SortedAscendingHeaderStyle BackColor="#0000A9" />
    <SortedDescendingCellStyle BackColor="#CAC9C9" />
    <SortedDescendingHeaderStyle BackColor="#000065" />
    <PagerStyle cssClass="gridpager" HorizontalAlign="Left" />  

</asp:GridView>

As you can see I have enabled to true the AllowPaging property.

This is how I bind the data:

DataSet dts = new DataSet();
OracleDataAdapter oad = new OracleDataAdapter(query, co.conn);

cmd.CommandText = query;
cmd.CommandType = CommandType.Text;

cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
OracleDataReader reader = cmd.ExecuteReader();

oad.Fill(dts);


g.DataSource = dts.Tables[0];
g.DataBind();

How can I improve the performance?

When I fill the dataset (oad.Fill(dts);) takes 10 minutes to complete. Is this because I set the 20000 records at once? Is there a way to show only the first 30 records and recall the data when the user paginates the gridview? Is there another way to improve the performance?

Servy
  • 202,030
  • 26
  • 332
  • 449
Naty Bizz
  • 2,262
  • 6
  • 33
  • 52

3 Answers3

7

If my understanding is correct, you want to add server paging

When you simply add AllowPaging="True" to the grid, by default, the GridView has no idea how to paging your data from the server, the paging is being executed in-memory after the whole results have been fetched from the database and this happens every time the GridView is bind

I think you want to add server paging (paging in the server and only sending to the client a small bunch of records), in order to do that, you could take advantage of the several ASP.Net data source controls.

Since you are doing the connection to your database manually, then you need to manually add paging code in your queries and map that code to the control

I think the only data source controls that can help you (since you are using Oracle as the database) are

  • SqlDataSource. Sadly it does not support server paging out-of-the-box, you would need to tweak it
  • ObjectDataSource. It can be easily integrated with the GridView control to provide paging, however you would need to manually add code to your queries or store procedures to paginate your data in the server
  • EntityDatasource. It's used to connect with your database when using EntityFramework

If you would be using EF or NHibernate for example, it would be easier, the code would look like:

g.DataSource = myContext.MyTable.Skip(pageIndex * pageSize).Take(pageSize);
g.DataBind();

Example using the ObjectDatasource

ASPX

    <asp:ObjectDataSource runat="server" ID="ods" TypeName="MyObject" EnablePaging="True"
        SelectMethod="FindPaging"
        MaximumRowsParameterName="pageSize"
        SortParameterName="sortColumn"
        StartRowIndexParameterName="startIndex"
        SelectCountMethod="FindPagingCount" onselected="ods_Selected"
    >
        <SelectParameters>
            <asp:Parameter Name="sortColumn" Type="String" />
            <asp:Parameter Name="startIndex" Type="Int32" />
            <asp:Parameter Name="pageSize" Type="Int32" />
        </SelectParameters>
    </asp:ObjectDataSource>

            <asp:GridView ID="grid" runat="server" AllowPaging="True" AllowSorting="True" PageSize="10"
                DataSourceID="ods" AutoGenerateColumns="true">
            </asp:GridView>

Data Component

[System.ComponentModel.DataObject]
public class MyObject
{
    [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
    public IEnumerable<employee> FindPaging(int startIndex, int pageSize, string sortColumn)
    {
        // place here your code to access your database and use the parameters to paginate your results in the server
    }

    [System.ComponentModel.DataObjectMethod(System.ComponentModel.DataObjectMethodType.Select)]
    public int FindPagingCount(int startIndex, int pageSize, string sortColumn)
    {
        var c = new DataClassesDataContext();

        return c.employees.Count();
    }
}
Jupaol
  • 21,107
  • 8
  • 68
  • 100
2

The easy solution would be to grab the top 30 rows, then when you grab the next set you grab the next 30 by doing top 30 where id > @lastid.

That way you only ever request 30 rows and dont have to bother with getting the whole recordset from the database.

Jonas
  • 185
  • 12
2

Paging simply means that it will only display 'pagesize' items at a time, but it will still need to get all of the data from the database before it can display those few items because that's what you're query is telling it to do.

What you need to do is modify the query so that it is only fetching 'pagesize' items, and then you need to add an event handler to the OnPageIndexChanging event so that you can re-query the database for the next 'pagesize' items. (Or preivous, or whatever, based on the paging options you have set. The event args will contain the page index the user asked for.)

If you do some web searching for "gridview paging" or similar you can find code examples, but they will vary quite a bit based on the database you're using, how you're fetching it, and so on.

Paging for oracle :

https://stackoverflow.com/a/241643/351383

Community
  • 1
  • 1
Servy
  • 202,030
  • 26
  • 332
  • 449