select top " + 每页行数 + " 所取字段 from 文章表 where id not in(select top " + 每页行数乘以页索引值 + " id from 文章表)我个人觉得这个SQL语句就是高效分页的核心,每次取一页数据而不是取整个表数据。
我在网上参考了一下别人做的例子总结出来的精华,就不知道我这精华臭不臭,呵呵。
看了一个高效分页存储过程例子,整个网页满满一大篇,头都看痛,我把整个例子拷贝到SQL查询分析器,一按右键执行,呵呵,好样啊,居然一点问题都没有,成功了!可是说老实话,我根本就没看懂那例子。我认为你再是天好的代码,你取数据的时候总得界定一个范围啊,还不是要进行内部计算。
我上面这个SQL语句,只要把每页行数和页索引值当作参数输入预先创建好的存储过程,不也是高效分页存储过程吗?我就是搞不懂那些例子干嘛要弄满满一大篇,是不是我这个语句执行时根本就不高效呢?
我的做法主要有两个步骤:
1、先[select count(id) from 文章表],得出总记录,从而计算页数(当然也考虑到余页问题);
2、在数据查询过程中,有个取数据时界定取值范围的内部计算,也就是后面那个SQL子句嘛。
我这样做,是不是在效率和性能上存在不足呢?
各位兄弟姐妹讨论讨论一下,谢谢!祝愿大家都进步哦。
我在网上参考了一下别人做的例子总结出来的精华,就不知道我这精华臭不臭,呵呵。
看了一个高效分页存储过程例子,整个网页满满一大篇,头都看痛,我把整个例子拷贝到SQL查询分析器,一按右键执行,呵呵,好样啊,居然一点问题都没有,成功了!可是说老实话,我根本就没看懂那例子。我认为你再是天好的代码,你取数据的时候总得界定一个范围啊,还不是要进行内部计算。
我上面这个SQL语句,只要把每页行数和页索引值当作参数输入预先创建好的存储过程,不也是高效分页存储过程吗?我就是搞不懂那些例子干嘛要弄满满一大篇,是不是我这个语句执行时根本就不高效呢?
我的做法主要有两个步骤:
1、先[select count(id) from 文章表],得出总记录,从而计算页数(当然也考虑到余页问题);
2、在数据查询过程中,有个取数据时界定取值范围的内部计算,也就是后面那个SQL子句嘛。
我这样做,是不是在效率和性能上存在不足呢?
各位兄弟姐妹讨论讨论一下,谢谢!祝愿大家都进步哦。
一看到这个就知道了
最好換成另外的替代方式
我的数据量是 109 万多点。
另一个分页算法(假设命名为 B):
select *
from (select top 当前页大小 *
from (select top 当前页*页大小 * from news order by id desc) a
order by a.id) b
order by b.id desc从执行计划来看,你的分页要稍优一点点,但从实际执行来看,B 要优一点。
如果把你的也加上 order by,那么不论是执行计划还是实际执行来说,B 都要优很多。另外,如果楼主只是按 id 排序的话,根据实际情况,还会有更优的分页。
100条万数据
速度还行
你的那句得该成
select top " + 每页行数 + " 所取字段 from 文章表 where id not in(select top " + 每页行数*(以页索引值 -1)+ " id from 文章表)
要不第一页不显示速度平均很好贴我给你测试的代码 SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["constr"].ConnectionString);
int ToatalCountRecord;//总记录数
int PageItem = 10;//每页显示的条数
int CurrentPage = 1;//当前页数
protected void Page_Load(object sender, EventArgs e)
{
if (!this.Page.IsPostBack)
{
if (Request.QueryString["page"] != null)
{
if (!Int32.TryParse(Request.QueryString["page"].ToString(), out CurrentPage))
{
Response.Write("请输入分页参数!");
Response.End();
return;
}
} this.BuidGrid();
} }
private void BuidGrid()
{
string s2 = "select top "+this.PageItem+" * from fed where serial not in (select top "+PageItem*(CurrentPage-1)+" * from fed )";
SqlDataAdapter da = new SqlDataAdapter(s2, conn);
DataSet ds = new DataSet();
//int startRecord = (CurrentPage - 1) * PageItem;
da.Fill(ds,"a");
this.DataList1.DataSource = ds.Tables["a"].DefaultView;
this.DataList1.DataBind();
SqlCommand comm = new SqlCommand("select count(*) from fed", conn);
conn.Open();
ToatalCountRecord = Convert.ToInt32(comm.ExecuteScalar());
conn.Close();
BuildPages();
}
private void BuildPages()
{
int Step = 5;//偏移量
int LeftNum = 0;//做界限
int RightNum = 0;//右界限
string PageUrl = Request.FilePath;
int PageCount = (int)Math.Ceiling((double)(ToatalCountRecord) / PageItem);
if (CurrentPage - Step < 1)
{
LeftNum = 1;
}
else
{
LeftNum = CurrentPage - Step;
}
if (CurrentPage + Step > PageCount)
{
RightNum = PageCount;
}
else
{
RightNum = CurrentPage + Step;
}
string OutPut = "";
if (CurrentPage > 1)
{
OutPut += " <a href='" + PageUrl + "?page=" + (CurrentPage - 1) + "'>" + "上一页" + " </a>";
}
for (int i = LeftNum; i <= RightNum; i++)
{
if (i == CurrentPage)
{
OutPut += " <font color=red>" + " " + "[" + i.ToString() + "]" + "" + " </font>";
}
else
{
OutPut += " <a href='" + PageUrl + "?page=" + i.ToString() + "'>" + " " + "[" + i.ToString() + "]" + " " + " </a>";
}
}
if (CurrentPage < PageCount)
{
OutPut += " <a href='" + PageUrl + "?page=" + (CurrentPage + 1) + "'>" + "下一页" + " </a>";
}
this.PageInfo.InnerHtml = OutPut;
}
--如果@OrderType不是0,就执行降序,这句很重要!endelsebegin set @strTmp = ">(select max" set @strOrder = " order by [" + @fldName +"] asc"endif @PageIndex = 1begin if @strWhere != '' set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from [" + @tblName + "] where " + @strWhere + " " + @strOrder else set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from ["+ @tblName + "] "+ @strOrder--如果是第一页就执行以上代码,这样会加快执行速度endelsebegin--以下代码赋予了@strSQL以真正执行的SQL代码set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from [" + @tblName + "] where [" + @fldName + "]" + @strTmp + "(["+ @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " ["+ @fldName + "] from [" + @tblName + "]" + @strOrder + ") as tblTmp)"+ @strOrderif @strWhere != '' set @strSQL = "select top " + str(@PageSize) +" "+@strGetFields+ " from [" + @tblName + "] where [" + @fldName + "]" + @strTmp + "([" + @fldName + "]) from (select top " + str((@PageIndex-1)*@PageSize) + " [" + @fldName + "] from [" + @tblName + "] where " + @strWhere + " " + @strOrder + ") as tblTmp) and " + @strWhere + " " + @strOrderend end exec (@strSQL)GO上面的这个存储过程是一个通用的存储过程,其注释已写在其中了。
最近我也再测试分页用的就是21楼的通用分页存储过程
不过我修改了下,因为原始的程序不支持多表联合查询,也不能按时间或点击数来排序,因为这个通用的分页存储过程在按照其他字段排序时,只要那个字段有相同的值出现时,分页有问题的。
后来没办法~自己修改,又没比较好的解决方按,我也只能用not in来了。
我测试过100W的数据,当主键是累加一的ID时(默认聚族索引),按ID排序,分页在SQL SERVER 中执行还是很快的,我的测试数据1秒不到。但是如果按其他字段排序的话,很慢,在11秒~17秒。
以上还只是在SQL SERVER 2005中直接执行存储过程的结果。如果在正式环境中测试的话,估计更慢。