5

我有大量数据(一个包含 20000 条记录的 sql 查询),用这些数据填充我的数据网格需要 10 分钟,这是我的 gridview 定义:

<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>

正如你所看到的,我已经启用了 AllowPaging 属性。

这就是我绑定数据的方式:

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();

我怎样才能提高性能?

当我填充数据集时 (oad.Fill(dts);) 需要 10 分钟才能完成。这是因为我一次设置了20000条记录吗?有没有办法只显示前 30 条记录并在用户对 gridview 进行分页时调用数据?还有其他方法可以提高性能吗?

4

3 回答 3

7

如果我的理解是正确的,你要添加服务器分页

当您简单地添加AllowPaging="True"到网格时,默认情况下,GridView不知道如何从服务器分页您的数据,分页是在从数据库中获取整个结果后在内存中执行的,并且每次GridView绑定时都会发生这种情况

我认为您想添加服务器分页(在服务器中分页并仅向客户端发送一小束记录),为此,您可以利用几个 ASP.Net 数据源控件。

由于您手动连接到数据库,因此您需要在查询中手动添加分页代码并将该代码映射到控件

我认为唯一可以帮助您的数据源控件(因为您使用 Oracle 作为数据库)是

  • SqlDataSource。遗憾的是它不支持开箱即用的服务器分页,您需要对其进行调整
  • 对象数据源。它可以很容易地与GridView控件集成以提供分页,但是您需要手动将代码添加到查询或存储过程中以在服务器中对数据进行分页
  • 实体数据源。它用于在使用 EntityFramework 时与您的数据库连接

例如,如果您使用 EF 或 NHibernate,它会更容易,代码如下所示:

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

使用示例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>

数据组件

[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();
    }
}
于 2012-07-18T14:39:32.917 回答
2

简单的解决方案是抓取前 30 行,然后当您抓取下一组时,您通过执行前 30 行(其中 id > @lastid)来抓取接下来的 30 行。

这样,您只需请求 30 行,而不必费心从数据库中获取整个记录集。

于 2012-07-18T14:40:04.850 回答
2

分页只是意味着它一次只显示“pagesize”项目,但它仍然需要从数据库中获取所有数据才能显示这几个项目,因为这就是您的查询告诉它要做的事情。

您需要做的是修改查询,使其仅获取“pagesize”项,然后您需要向事件添加事件处理程序,OnPageIndexChanging以便您可以重新查询数据库以获取下一个“pagesize”项。(或者之前的,或者其他的,基于你设置的分页选项。事件参数将包含用户要求的页面索引。)

如果您在网络上搜索“gridview 分页”或类似内容,您可以找到代码示例,但它们会根据您使用的数据库、获取它的方式等而有很大差异。

oracle 的分页:

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

于 2012-07-18T14:40:26.657 回答