主要是被搞得一头雾水,在学校里老师就说sqlserver2000很差,比mysql都不如,希望2005的能好一点,唉

解决方案 »

  1.   

    http://blog.csdn.net/hertcloud/category/281167.aspx
    通用的 肯定 效率来说会 降低但是通用的 也可以很 容易 根据print输出写成特定的分页过程
      

  2.   

    我特别要请大家注意:不要用:not in,exist 之类的关键字来分页,速度可以说除了慢还是慢,
    用50万的数据量来测试就会很明显了,
    另外 那种  where (1=1) 形式也是不可取的,因为这种形式不会使用索引的
    还有那种什么 order by id 明显就是不可取,那个id必须是唯一健,侵入性非常强
      

  3.   

    在学校里老师就说sqlserver2000很差,比mysql都不如?你们老师也太差劲了.
    sql 2000出道的时候, mysql都不支持存储过程,不支持事务,不支持左右全连接, 不支持嵌套查询,不支持全文索引,没有查询分析器,没有事件探查器,只有一个php的mysqladmin. 很久没用过了,不知道现在支不支持. 不过现在已经是sql 2005了当然我十分崇拜独立开发出mysql的那些个热血青年.
      

  4.   

    你不能用行号的效率和一般字段进行比较,没有可比性。
    行号是聚簇索引,如果SQL Server的排序字段也建立聚簇索引,它们的效率是一样的,这点如果你的数据库老师没讲过,那说明他水平有限。SQL Server 2000和Oracle相比,各有优缺点。Oracle占用资源巨高,SQL Server 2000则在处理巨大量数据上效率低,且无法充分利用硬盘DMA通道的优势。一般数据量不是很大还是用SQL Server,如果上G的数据就选Oracle。
    关于MySQL,和楼上观点一样,崇拜开发者,但其应用,也只能局限于网站这样数据量极小的情况了。
      

  5.   

    假如这种情况呢,楼主有没有考虑select * from table_a A,table_b B where A.id=B.id and a.date=getdate()...这样你上样的存储过程还成立吗?如果更复杂的联表ABCD四个表了,可以分页吗?
    (-_______-...当然除了视图做过渡,不过这样就没意义了,速度慢了)
      

  6.   

    同意xiahouwen(武眉博<活靶子.NET>) 的观点
      

  7.   

    mimijidi() ( ) 信誉:100    Blog   加为好友  2007-5-17 17:35:48  得分: 0  
     
     
       
    主要是被搞得一头雾水,在学校里老师就说sqlserver2000很差,比mysql都不如,希望2005的能好一点,唉  
     
    --------------
    这样为人师  。。迷糊~~
      

  8.   

    还是没有深入研究,分页也不知这三种,还有两中没有提及。select top PageSize @id = ID from Table
    select top [PageSize * (PageIndex - 1) + 1] * from Table where ID >= @ID这个效率就高了,当然不够通用。select top 10 [*] from 
    select top 10 [*] from 
    (
             select top 20 [*] from [Table]
             order by [AddedDate] desc,[ID]
    ) as aa order by [AddedDate] ,[ID] desc
    ) as aa order by [AddedDate] desc ,[ID] 这个就通用了,  order by [AddedDate] desc,[ID] 这里还可以加更多的排序字段。至于多表联合可以做成视图来简化。至于效率,算法不是主要的,设置合理的索引才是最主要的!唯一的缺点:最后一个排序字段不能有重复值。有的话会影响排序,影响的程度要看重复值的多少和位置。不过也好解决,加一个自增字段就可以了。select [*] from [Table] where [ID] in (
        select top 10 [ID] from 
    (
             select top 20 [ID] ,AddedDate from [Table]
             order by [AddedDate] desc,[ID]
    ) as aa order by [AddedDate] ,[ID] desc
    )order by [AddedDate] desc,[ID]这是一个折衷的算法,通用和效率的折中,两者都是比较高的。详细看这里
    http://blog.csdn.net/jyk/archive/2007/03/01/1518354.aspx
      

  9.   

    ls说的第一种的算法有一个严重的效率问题:中间的select 后都是 *  ,其实有用的字段只有一两个,为什么不管青红皂白都提出来呢?提取需要的字段,效率就高了。用了三个 * ,其实只有最外层的才是有效的,里面的两个都有“浪费”的嫌疑。
      

  10.   

    select top PageSize @id = ID from Table
    select top [PageSize * (PageIndex - 1) + 1] * from Table where ID >= @ID
    我就是用这个,千万数据,ID,int,聚集索引,少于100毫秒
      

  11.   

    其中这句占了99%的查询成本:select top PageSize @id = ID from Table
      

  12.   

    再次整理sqlserver常用分页的主要弊病:1.使用主键或者唯一列来排序才能达到分页目的(那种两次top的方案除外,但是排序列也不能包含空值),目前基本上80%的表的都是根据添加时间来倒序的,很少根据主键或者唯一健来排序2.侵入行强!!什么是侵入性?就是强迫你要做这个做那个才能达到目的,我不想排序都不行,我不想根据那什么ID的来分页都不行,强迫你做事情你愿意吗???很多分页算法都带那什么where ID 如何如何MAX(ID)等等等等,看一眼就打一个大叉!3.假设页大小是10,但数据库真正的结果集只有53条纪录,那么第六页是不是就是只有3条??,但是使用top方式分页,如果最后一页纪录不足10条会自动补足十条(重复纪录),不信的话自己去测试,这是不是很可笑??莫名其妙的多出一些重复纪录出来.对于编程人员来说无所谓,如果客户没有意见就好,如果客户找你麻烦怎么办??问题就出在第一个TOP,它是TOP10 !!TOP 页大小!!! 如果这10能灵活一点就好
    4.如果order by 字段的数据列包含空值,分页效果可能就会和实际的不符,不信的话可以试试
    ----------------------------------------*当然我也写不出什么比较好的分页存储过程,我使用过Hibernate,里面的sqlserver分页算法是基于两次Top三次颠倒数据集实现分页,Hibernate的作者Gaving King也算是个数据库专家,这说明第一种方案还是比较通用的,有批评才有进步,才会想出更好的方法出来,我是这么想的
    -----------------------------------------*2005的基于行号的分页有空要试试
    -----------------------------------------
    *我上面写的那个存储过程是仓促之作,如果多表连接再加上排序就要出问题了,主要是那个order by字段的表前缀处理不好,会解决的_________________________________________
    *至于mysql和mssql哪个好,我也不想去讨论,可能mssql用得比较多,才觉得它很差,这个毛病那个毛病的,如果你有开发java,你就知道mssql又要多几种差的地方,正如微软window系统用的人多,结果找出来的毛病也多一样,虽然我写不出数据库,在这里我就好像是客户在使用了一种产品以后点出了一些感慨-----------------------------------------
    *贴一个oracle分页,有比较才知道不足
    SELECT * FROM (        
                 SELECT my_table.* , rownum AS my_number FROM (  
        
                /** 这里写实际的需要查询的SQL语句,爱什么写就怎么写,主动权在程序员**/
                    select * from mytable where ... order by ...           ) AS my_table WHERE rownum <=30  /**这里是一页中的最后一条记录**/                   ) WHERE my_number >=20 /**这里是一页中的第一条记录**/
    *当然oracle是sqlserver不能比的,但我相信微软那么的开发人员系统都能开发,把sqlserver的分页稍微搞得简便一点咋就没有办法办到?? 估计微软只做大事不做小事-------------------------------------
    算了无所谓啦,随便开发吧,有什么用什么,研究知道得太多对自己也没有什么好处,反而经常要想着如果去改进
      

  13.   

    我都懒得用Sql来分页,1来麻烦,2来又不通用,容易在特殊情况中出问题System.Data.Common.DbDataAdapter.Fill(System.Data.DataSet dataSet, int startRecord, int maxRecords, string srcTable)
      

  14.   

    --下面这个是修改过的,照样很糟糕,看过程长度就知道,那么多字符,繁琐,可是没有办法
    --两次top分页方案,如果最后一页纪录数目不足规定的页大小,会自动补足纪录数
    alter proc com_Pagination
    @tbName varchar(200),      --表名,可多表,逗号分隔
    @tbFields varchar(500)='*',--字段名,如果多表请带前缀
    @whereStr varchar(300)='', --where子句,可为空,不带where
    @orderStr varchar(300),    --排序字段,可多个,要带desc或asc,不带order by,必须,不能为空,多表要带前缀a-e
                               --排序字段不能有空值,或者在where中排除空值或者用isnull函数解决@needCound bit = 0,        --是否需要得到纪录总数
    @pageIndex int =0,         --页索引
    @pageSize int=10,          --页大小
    @recordCount BIGINT =0 output, --返回纪录总数,如果用DataReader提取过程结果集,必须dr.close或者conn.close,才能获得过程的返回值,oracle中的DataReader不会有这种情况
    @pageCount int =0 output       --返回页总数as
    declare @sql nvarchar(1300)      --主sql语句
    declare @orderStr2 varchar(300)  --order by子句
    declare @orderStr3 varchar(300)  --order by子句
    declare @tempStr varchar(300)set @orderStr = LOWER(@orderStr)
    set @tempStr = REPLACE(@orderStr,' desc','')
    set @tempStr = REPLACE(@tempStr,' asc','')
    set @tbFields = @tbFields + ',' + @tempStr
    set @orderStr2 = REPLACE(@orderStr,' desc',' @a@')
    set @orderStr2 = REPLACE(@orderStr2,' asc',' @d@')
    set @orderStr2 = REPLACE(@orderStr2,' @a@',' asc')
    set @orderStr2 = REPLACE(@orderStr2,' @d@',' desc')set @orderStr3 = REPLACE(@orderStr,'a.','')
    set @orderStr3 = REPLACE(@orderStr3,'b.','')
    set @orderStr3 = REPLACE(@orderStr3,'c.','')
    set @orderStr3 = REPLACE(@orderStr3,'d.','')
    set @orderStr3 = REPLACE(@orderStr3,'e.','')set @orderStr = ' order by ' + @orderStr
    set @orderStr2 = ' order by ' + @orderStr2
    set @orderStr3 = ' order by ' + @orderStr3  if(@whereStr is not null and @whereStr !='' )
         set @whereStr = ' where ' + @whereStr
      else
         set @whereStr = ''  if(@needCound != 0 or @pageIndex = 0) --以下获得纪录总数
         begin
           DECLARE @R BIGINT
           SET   @sql=  N'select @R=count(*) from  '+@tbName +@whereStr
           EXEC  SP_EXECUTESQL @SQL,N'@R BIGINT OUTPUT',@R OUTPUT
           SET   @recordCount = @R
           set   @pageCount = ((@recordCount-1)/@pageSize)+1 
         end
      
      if(@pageIndex<2) --如果是第一页
         begin
          set @pageIndex = 1
          set @sql='select top '+ str(@pageSize) + ' '+ @tbFields + ' from ' + @tbName + @whereStr + @orderStr;
         end
     
      else             --其它页
         begin
         SET @sql= 'SELECT * FROM ('
                   + 'SELECT TOP ' + STR(@pageSize) + ' * FROM ('
                      + 'select top ' + STR(@pageSize*@pageIndex) + ' '+ @tbFields + ' FROM '
                          + @tbName + @whereStr  + @orderStr  + ') as a'
                             + @orderStr2 + ') as b' + @orderStr3
         end
      print @sql  
      EXEC SP_EXECUTESQL @sql 
       
    --测试
    --pub数据库,三表连接,结果集43条,页大小10,但第五页还是10条(有一些是重复纪录)
    declare @a BIGINT,@b BIGINT
    exec com_Pagination 'employee a,jobs b,publishers c','a.emp_id,a.fname+a.lname as ename,b.job_desc,c.pub_name','a.job_id=b.job_id and a.pub_id=c.pub_id','a.hire_date desc',true,4,10,@a output,@b output
    print @a
    print @b--原始的结果集,分页就是基于下面这个
    select * from employee e,jobs j,publishers p where e.job_id=j.job_id and e.pub_id=p.pub_id order by hire_date desc
      

  15.   

    1、为何一定要用存储过程,在存储过程里组串,在程序里不行吗?2、为何不用视图?用了视图效率就会差吗?还是不便于管理?3、为何只能用一种分页算法?一个项目里只能用一种算法?根据情况使用两种或者三种不行吗?4、索引!往往被忽略的东东,但是往往他确是很重要的!5、where id 。谁说ID一定代表主健了,其实这里的ID 代表“排序字段”,可能这么写就不会误会了,where OrderByColumn  (排序字段)。>>看一眼就打一个大叉 再看一眼好吗?举一反三,触类旁通,是不是应该用一下呢?
      

  16.   

    "where id " ,这个id不一定是主键没有错,但是最好是主键或者唯一健,否则经过max(id),再去分页就不符实际分页情况,甚至有些人为了分页再往表里面增加一个自增长列,表的主键用自增长列
    有它的弊病,建议不要(我指的是一些比较重要的表噢)sqlserver的分页好与不好,争论太多于事无补,随便搜一个sqlserver的分页存储过程,有哪一篇不是长篇大论的看得你眼皮发抖,这足以证明sqlserver的分页方案确实不好,繁琐,侵入性!!有待我们再去改善,有待我们再去探讨,贴这篇文章的目的是想问问网友们有没有更好的方案,如何做?有谁认为sqlserver的那几种分页方案挺好的!请站出来说它好的地方