smhy8187

 

千万级数据分页详细设计

http://blog.csdn.net/46539492/archive/2008/02/14/2092542.aspx

 千万级数据分页详细设计   文章指数:0  CSDN Blog推出文章指数概念,文章指数是对Blog文章综合评分后推算出的,综合评分项分别是该文章的点击量,回复次数,被网摘收录数量,文章长度和文章类型;满分100,每月更新一次。

贴的html代码太难看了。直接贴成黑白的吧,能看清楚。

千万级数据分页详细设计

1. 引言
1.1目的
为适应大数据量分页的需要,为以后千万级数据分页提供解决方法或者参考,节省开发时间,特制定本详细设计方案

1.2主要阅读对象
脚本设计人员

1.3参考资料
http://www.cnblogs.com/SGSoft/archive/2004/10/23/55800.html

2. 详细设计
2.1分页存储过程
2.1.1简介
2.1.2分页存储过程代码
以下代码是网上找的分页存储过程,我是在原存储过程的基础上加了一个@IsCount bit = 0, 主要是用来返回纪录总数,当为非0值时返回。下面注释部分是原作者的测试部分。我在本机sql server 2005上的测试是在10000011纪录中查询第100000页,每页10条纪录按升序和降序时间均为0.38秒,测试语法如下:exec GetRecordFromPage tbl_Briefness,I_BriefnessID,10,100000,其中在tbl_Briefness表I_BriefnessID字段上建立了索引。

 

/*

  经测试,在14483461 条记录中查询第100000 页,每页10 条记录按升序和降序第一次时间均为0.47 秒,第二次时间均为0.43 秒,测试语法如下:

  exec GetRecordFromPage news,newsid,10,100000

  news 为表名, newsid 为关键字段, 使用时请先对newsid 建立索引。

 

  函数名称: GetRecordFromPage

  函数功能: 获取指定页的数据

  参数说明: @tblName      包含数据的表名

           @fldName      关键字段名

           @PageSize     每页记录数

           @PageIndex    要获取的页码

           @OrderType    排序类型, 0 - 升序, 1 - 降序

           @strWhere     查询条件(注意: 不要加where)

  创建时间: 2004-07-04

  修改时间: 2008-02-13

*/

Alter PROCEDURE [dbo].[GetRecordFromPage]

    @tblName      varchar(255),       -- 表名

    @fldName      varchar(255),       -- 字段名

    @PageSize     int = 10,           -- 页尺寸

    @PageIndex    int = 1,            -- 页码

    @OrderType    bit = 0,            -- 设置排序类型, 非0 值则降序

    @IsCount bit = 0, -- 返回记录总数, 非0 值则返回

    @strWhere     varchar(2000) = ''  -- 查询条件(注意: 不要加where)

   

AS

 

declare @strSQL   varchar(6000)       -- 主语句

declare @strTmp   varchar(1000)       -- 临时变量

declare @strOrder varchar(500)        -- 排序类型

 

if @OrderType != 0

begin

    set @strTmp = '<(select min'

    set @strOrder = ' order by [' + @fldName + '] desc'

end

else

begin

    set @strTmp = '>(select max'

    set @strOrder = ' order by [' + @fldName +'] asc'

end

 

set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

    + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

    + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

    + @fldName + '] from [' + @tblName + ']' + @strOrder + ') as tblTmp)'

    + @strOrder

 

if @strWhere != ''

    set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

        + @tblName + '] where [' + @fldName + ']' + @strTmp + '(['

        + @fldName + ']) from (select top ' + str((@PageIndex-1)*@PageSize) + ' ['

        + @fldName + '] from [' + @tblName + '] where ' + @strWhere + ' '

        + @strOrder + ') as tblTmp) and ' + @strWhere + ' ' + @strOrder

 

if @PageIndex = 1

begin

    set @strTmp = ''

    if @strWhere != ''

        set @strTmp = ' where (' + @strWhere + ')'

 

    set @strSQL = 'select top ' + str(@PageSize) + ' * from ['

        + @tblName + ']' + @strTmp + ' ' + @strOrder

end

if @IsCount != 0

set @strSQL = 'select count(' + @fldName + ') as Total from [' + @tblName + ']'

exec (@strSQL)

2.2千万级数据分页实现
2.2.1简介
这次分页我是用Gridview来实现的,测试时间没算,但基本上从10000011纪录中一次查询25条纪录,在10万页以内,时间花费 在1秒以内,10万页以上也不超过2秒。使用其他控件比如DataGrid,DataList或者DataReapter应该花费的时间更短。

2.2.2适用对象
服务器端控件Gridview,DataGrid,DataList,DataReapter等数据绑定控件

2.2.3分页实现
分页效果图如下:


前台控件代码和功能描述如下

控件代码
 功能描述
 
<asp:GridView ID="GridView1" runat="server" AllowPaging="false" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" PagerSettings-Visible="false"

                    Width="100%" height="35">
 显示当前页数据,其中AllowPaging="false",就是去掉自带的分页功能
 
<asp:Label ID="lblCurrentPage" runat="server"></asp:Label>
 用来纪录或者显示当前页
 
<asp:Label ID="lblRecodeCount" runat="server"></asp:Label>
 用来纪录或者显示所有纪录数
 
<asp:Label ID="lblPageCount" runat="server"></asp:Label>
 用来纪录或者显示总页数
 
<asp:LinkButton ID="lnkbtnFrist" runat="server" OnClick="lnkbtnFrist_Click"><font face=webdings color="red">9</font></asp:LinkButton>
 首页,点击则翻到第一页
 
<asp:LinkButton ID="lnkbtnPre" runat="server" OnClick="lnkbtnPre_Click"><font face=webdings color="red">7</font></asp:LinkButton>
 上一页,点击进入上一页
 
<asp:LinkButton ID="lnkbtnNext" runat="server" OnClick="lnkbtnNext_Click"><font face=webdings color="red">8</font></asp:LinkButton>
 下一页,点击进入下一页
 
<asp:LinkButton ID="lnkbtnLast" runat="server" OnClick="lnkbtnLast_Click"><font face=webdings color="red">:</font></asp:LinkButton>
 末页,点击进入最后一页
 
<asp:TextBox ID="txtPageIndex" runat="server" style="width:40px;" onkeypress="myKeyDown();"></asp:TextBox>
 输入要跳转到的某一页的具体数字,只允许输入大于0的数字,输入0或者大于总页数时,弹出警告提示
 
<asp:Button ID="BtnChangePage" runat="server" Text="GO" OnClick="BtnChangePage_Click" />
 执行具体的页面跳转
 

 

前台代码如下:

 

<form id="form1" runat="server">

   <table width="98%" align="center" class="maintableborder">

        <tr>

            <td height="35" style="text-align: left;">

                <asp:Label ID="lbAddProposal" runat="server">  <img src="../images/025.gif" width="13" height="13" /> <br /></asp:Label>

                <asp:GridView ID="GridView1" runat="server" AllowPaging="false" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" PagerSettings-Visible="false"

                    Width="100%" height="35">

                    <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

                    <RowStyle BackColor="#EFF3FB" />

                    <EditRowStyle BackColor="#2461BF" />

                    <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> 

                    <PagerStyle ForeColor="White" VerticalAlign="Top" BackColor="Transparent"  />                

                    <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

                    <AlternatingRowStyle BackColor="White" />

                    <Columns>

                        <asp:TemplateField HeaderText="序号">

                            <ItemTemplate>

                                <%# Container.DataItemIndex+1 %>

                            </ItemTemplate>

                        </asp:TemplateField>

                        <asp:BoundField DataField="I_BriefnessID" HeaderText="ID" />

                        <asp:BoundField DataField="I_KMID" HeaderText="科目" />

                        <asp:BoundField DataField="C_Recno" HeaderText="试题号" />        

                        <asp:BoundField DataField="M_Title" HeaderText="题面" />

                        <asp:BoundField DataField="C_Answer" HeaderText="答案" /> 

 

                    </Columns>

                </asp:GridView>

                <asp:Panel ID="panPage" runat="server">

                 <table width="100%" style=" height:20px; border:solid 1px #cccccc;" cellpadding="0" cellspacing="0" >

            <tr>

                <td align="right">

                   当前第

                    <asp:Label ID="lblCurrentPage" runat="server"></asp:Label>页,

                    总共<asp:Label ID="lblRecodeCount" runat="server"></asp:Label>条纪录,

                    共<asp:Label ID="lblPageCount" runat="server"></asp:Label>页,

                    <asp:Label ID="Label1" runat="server"></asp:Label>

                    <asp:LinkButton ID="lnkbtnFrist" runat="server" OnClick="lnkbtnFrist_Click"><font face=webdings color="red">9</font></asp:LinkButton>

                     <asp:LinkButton ID="lnkbtnPre" runat="server" OnClick="lnkbtnPre_Click"><font face=webdings color="red">7</font></asp:LinkButton>

                     <asp:LinkButton ID="lnkbtnNext" runat="server" OnClick="lnkbtnNext_Click"><font face=webdings color="red">8</font></asp:LinkButton>

                    <asp:LinkButton ID="lnkbtnLast" runat="server" OnClick="lnkbtnLast_Click"><font face=webdings color="red">:</font></asp:LinkButton>

                    跳转到第<asp:TextBox ID="txtPageIndex" runat="server" style="width:40px;" onkeypress="myKeyDown();"></asp:TextBox>页<asp:Button ID="BtnChangePage" runat="server" Text="GO" OnClick="BtnChangePage_Click" />                  

              </td>

            </tr>

        </table>

        </asp:Panel>

        <asp:Label ID="lbNoMessage" Text="当前题库下没有任何试卷一定方案" runat="server" ForeColor="red"></asp:Label>

          </td>

        </tr>

    </table>

    </form>

后台代码如下:

相关解释请看代码注释

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

 

public partial class _Default : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        if (!Page.IsPostBack)

        {

            TestDataCount();

            BindPaperDefineProgramme(1);

        }

    }

 

    #region 绑定试卷定义方案列表

    /// <summary>

    /// 统计该表的所有纪录

    /// </summary>

    private void TestDataCount()

    {

        DataTable dt = null;

        try

        {

            //public static DataTable GetTestData(string tableName, int pageSize, int pageIndex,string columnName,bool isCount)

            //第一个参数为要查询的表,第二个参数为每页的纪录数,这里定为25,第三个为页码,这里初始化为第1页,第四个参数为表的字段

            //,第五个参数为是否返回纪录总数,这里为true表示返回纪录总数

            dt = ExecProc.GetTestData("tbl_Briefness", 25, 1, "I_BriefnessID",true);

        }

        catch (Exception ex)

        {

            Response.Write(ex.Message);

            return;

        }

        if (dt.Rows.Count == 0)

        {

            GridView1.Visible = false;

            panPage.Visible = false;

            lbNoMessage.Visible = true;

        }

        else

        {

            GridView1.Visible = true;

            panPage.Visible = true;

            lbNoMessage.Visible = false;

            lblRecodeCount.Text = dt.Rows[0]["Total"].ToString();

            lblCurrentPage.Text = "1";//初始化当前页为第一页

            int recodeCount = int.Parse(dt.Rows[0]["Total"].ToString()); //获取纪录总数

            int pageSize = recodeCount % 25 == 0 ? recodeCount / 25 : recodeCount / 25 + 1;//计算总页数

            lblPageCount.Text = pageSize.ToString();//保存总页数

        }

 

    }

    #endregion

 

    #region 绑定试卷定义方案列表

    /// <summary>

    /// 根据当前页码查询需要的数据

    /// </summary>

    /// <param name="pageIndex">页码</param>

    private void BindPaperDefineProgramme(int pageIndex)

    {

        DataTable dt = null;

        try

        {

            dt = ExecProc.GetTestData("tbl_Briefness", 25, pageIndex, "I_BriefnessID", false); //根据页码查询需要的纪录

        }

        catch (Exception ex)

        {

            Response.Write(ex.Message);

            return;

        }

        if (dt.Rows.Count == 0)

        {

            GridView1.Visible = false;

            panPage.Visible = false;

            lbNoMessage.Visible = true;

        }

        else

        {

            GridView1.Visible = true;

            panPage.Visible = true;

            lbNoMessage.Visible = false;

            GridView1.DataSource = dt;

            GridView1.DataBind();

        }

        int pageCount = int.Parse(lblPageCount.Text); //获取总页数

        if (pageIndex == 1) //如果是第一页,则第一页灰显,作用是避免不必要的点击造成没必要的数据传输

        {

            lnkbtnFrist.Enabled = false;

        }

        else

        {

            lnkbtnFrist.Enabled = true;

        }

        if (pageIndex > 1) //如果当前页大于1,则上一页显示,否则灰显

        {

            lnkbtnPre.Enabled = true;

        }

        else

        {

            lnkbtnPre.Enabled = false;

        }

        if (pageIndex < pageCount)//如果当前页小于总页数,则下一页显示,否则灰显

        {

            lnkbtnNext.Enabled = true;

        }

        else

        {

            lnkbtnNext.Enabled = false;

        }

        if (pageIndex == pageCount)//如果当前页为最后一页,则末页灰显

        {

            lnkbtnLast.Enabled = false;

        }

        else

        {

            lnkbtnLast.Enabled = true;

        }

 

    }

    #endregion

 

    #region 翻页相关的事件

    /// <summary>

    /// 处理翻页事件

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    protected void lnkbtnFrist_Click(object sender, EventArgs e) //第一页

    {

        lblCurrentPage.Text = "1";

        BindPaperDefineProgramme(1);

    }

    protected void lnkbtnPre_Click(object sender, EventArgs e) //上一页

    {

        int pageIndex = int.Parse(lblCurrentPage.Text);

        if (pageIndex > 0)

        {

            pageIndex--;

            lblCurrentPage.Text = pageIndex.ToString();

            BindPaperDefineProgramme(pageIndex);

        }

    }

    protected void lnkbtnNext_Click(object sender, EventArgs e)//下一页

    {

        int pageIndex = int.Parse(lblCurrentPage.Text);

        int pageCount = int.Parse(lblPageCount.Text);

        if (pageIndex < pageCount)

        {

            pageIndex++;

            lblCurrentPage.Text = pageIndex.ToString();

            BindPaperDefineProgramme(pageIndex);

        }

    }

    protected void lnkbtnLast_Click(object sender, EventArgs e)//末页

    {

        lblCurrentPage.Text = lblPageCount.Text;

        BindPaperDefineProgramme(int.Parse(lblPageCount.Text));

    }

    #endregion

    protected void BtnChangePage_Click(object sender, EventArgs e)//跳转到指定页

    {

        int pageIndex = int.Parse(txtPageIndex.Text);

        int pageCount = int.Parse(lblPageCount.Text);

        if (pageIndex == 0)//如果为0,则提示错误

        {

            Response.Write("<Script>alert('请输入正确的页数!');</script>");

            return;

        }

        if (pageIndex > pageCount)//如果大于总页数则提示错误

        {

            Response.Write("<Script>alert('请输入正确的页数!');</script>");

            return;

        }

        lblCurrentPage.Text = pageIndex.ToString();

        BindPaperDefineProgramme(pageIndex);

    }

}


posted on 2008-04-10 08:24  new2008  阅读(547)  评论(1编辑  收藏  举报

导航