>>用ASP直接访问数据 
使用recordset的PageSize,AbsolutePage,PageCount属性分页

解决方案 »

  1.   

    同意 hydnoahark(诺亚方舟) 的方法,也可以在COM中使用这种方法 
      

  2.   

    to playyuer(女㊣爱) :
    你有什么好建议吗?
    to hydnoahark(诺亚方舟) to  lcooky(今夜无雪) :
    你是真的不懂吗? 如果要用AbsolutePage ,哪你得用Keyset数据集 对一万条以上的表你可
    以试试速度。谢谢!
      

  3.   

    用ODBC就这样啦,要速度快,你就用C/S结构,自己传送请求报文,再写个后台。以前我用ODBC连接数据库,在一个二三十万条记录的表中搜索记录,情况也跟你差不多。ODBC虽好用,但资源消耗很厉害,不适合大数据量的。
      

  4.   

    呵呵,你真的要改用报文?那对你程序的整个结构改动很大,而且还要写后台接收报文的出来程序。要不你只就这个功能用这种结构,返回结果写在文件里面,传送到前台,由前台程序直接从返回文件读取,那速度肯定会比你ODBC快。
      

  5.   

    至于用不用报文不重要重要的
    可以用OLE DB 或SYBASE API
    是如何实现最费时的是定位记录中从某一记录取起。
    你说呢? 
      

  6.   

    听说MYSQL可以执行Select 150 200 * From TABLE ":)
      

  7.   

    我觉得似乎没有必要同时显示那么多的结果,既然用户只要第8000条以后的数据,为什么还要读取前面的数据呢?
    建议你修改查询的步骤,首先显示一些分类数据,然后根据分类显示明细数据,比如对于普通的销售查询可以这样做:
    1:显示可以分类的对象(日期,销售部门,客户.....)
    2:客户选择其中的一个分类,然后据此进行groupby得到结果返回,同时显示一些必要的合计(比如销售数量、金额之类的)
    3:客户选择某一项,这个时候可以显示明细数据(首先显示前面300条,使用top 300实现),如果客户选择了“更多”,再全部显示。
      

  8.   

    先声明一下,我是菜鸟,刚学VB,有个想法不知道行不行
    声明一个变量n每次查询记住他要的最后一条记录的位置
    点击下一页时候
    打开数据库便直接move n
    返回50条
    n=n+50

    别骂我,我什么也不懂,没试过
      

  9.   

    对于BlackIceCN(星际浪子)的方法其实直接使用服务器端游标即可,无需使用中间变量。
      

  10.   

    to _1_(阿呆)(大冬瓜) 
    用在SYBASE里有什么好的解决办法呢
    to bucher(bucher) 
    不是所有的数据都可能分类,用户查询出来的结果可能超出一万条,所以你的方法无法解决实际问题。
    to BlackIceCN(星际浪子) 
    我程序也是用变量  
    DataRecord.Move(lStartRow) ------但是正是这句速度最慢
    类似的想法 是用ADO BOOKMARK 但 BOOKMARK只能用于当前数据集,翻页时是重新打开数据集谢谢!
      

  11.   

    1.使用存储过程(我不熟悉Sybase,不知道支不支持存储过程),每次返回一页数据
    2.不知道你的表设计,如果可以,尽可能优化你的表设计,一些表设计可以保证你的ASP中可以直接定位一页数据位置并返回
    3.使用ISAPI代替ASP
      

  12.   

    to hydnoahark(诺亚方舟) 
    1.SYBASE 支持存储过程,但我不知道能还传很复杂的查询条件进行给一个存储过程,(好象SYBASE 不支持动态的SQL语句)
    2.表结构如下:
    create table dbo.SH_QYBASE_ZT (
    NBXH    varchar(22) not null,
    QYMC    varchar(100)    null,
    ZS  varchar(100)    not null,
    YZBM    varchar(6)  null,
    FDDBR  varchar(40) not null,
    DH  char(30)    null,
    ZCZB    money  not null,
    BZ  char(3) null,
    QYLX    varchar(4)  not null,
    JYFW    text    not null,
    ....
    constraint SH_QYBASE_ZT_PRIMARY_KEY PRIMARY KEY NONCLUSTERED ( NBXH ) 
    3.使用ISAPI代替,应该会提高速度,但更主要的问题应该在数据库操作方面 
    谢谢你
      

  13.   

    Set DataRecord.Open "Select * From TABLE ",DataConnect, adOpenForwardOnly, adLockReadOnly  
    在这里面想想办法!有没有可能加个where语句,不要一下子就从数据库中将记录全都select出来!
      

  14.   

    to BlackIceCN(星际浪子)
    有理解你的想法,但可能不行
    第一系统不只一个表并且表有100万条记录用户查询条件是不定的
    第二打开所的的记录就已经要花费很多时间从本地硬盘也要花费很多时间,提高效率的可能性很少
    这是我的看法,你觉得呢!
      

  15.   

    我再给你提个建议,假如8000条记录可分成100页,你就一次性生成100个静态的Html文件,用序号命名文件,文件之间的链接也直接写在文件里面。然后你重定向到第一个文件,这样用户浏览的时候就快很多了,当然你还要区分不同用户的文件。
    哪个用户会浏览8000条记录,需要吗,不需要吗,需要吗,不需要吗,需要吗,不需要吗,
      

  16.   

    我一般是保存上一页的max key,向前翻在SQL语句中where用上一页的max key,向后翻在SQL语句中用本页的max key,每次只取10条。
      

  17.   

    to sweet(阿甘) 
    谢谢,但数据库的内容是会变动的
    还有,这不是需不需要的问题 而是能不能够的问题,如果是C/S结构你根本不用考虑这类问题
    我的程序提供用户查询界面,提供翻页的第N页界面,你很难保证用户不会查询于多于20000条记录的结果集,也不能保证用户不会在页码框中输入大于350的数,你说呢
    to jacklondon(jacklondon) 
    这样也不能,如果查询语句有排序功能什么办?
      

  18.   

    用varchar类型的字段作为主键当然很慢,建议增加一个整型的字段作为主键,这样速度将会大大提高;如果还觉得不行,可以多建两个索引。
      

  19.   

    所有的测试都是基于SQL Server的,你用Sybase的话可能需要适当的修改。
    我假设你的查询中使用且只使用NBXH升序排序。
                              ~~~~~~~~~~~~
    我的思路:
    你分两步来根据用户输入的页数返回特定的一页纪录
                                       ~~~~~~~~
    1。使用SQL语句返回这一页的第一个(最小)纪录的NBXH
    2。select top 每页纪录数 * from SH_QYBASE_ZT where NBXH>=FirstRec order by NBXH 即可。下面是关于第一步的思路:
    declare @pagesize int --每页纪录数
    declare @reccounts int --数据库总的纪录数
    declare @pagecounts int --根据每页纪录数和数据库总的纪录数返回的总页数
    declare @intBeginID int --特定页的第一条(最小)纪录
    declare @intRowCount int --临时变量select @pagesize=10 --每页10条纪录
    select @reccounts=count(1) from SH_QYBASE_ZT --返回所有纪录数
    if @reccounts/@pagesize*@pagesize=@reccounts
      set @pagecounts=@reccounts/@pagesize  --返回总页数
    else
      set @pagecounts=@reccounts/@pagesize+1 --返回总页数set @intRowCount=(@currentpage-1)*@pagesize+1 --特定页的第一条(最小)纪录在所有纪录中的位置(使用了order by)SET ROWCOUNT @intRowCount --SQL Server的功能,作用类似top @intRowCount 
    select @intBeginID=NBXH from SH_QYBASE_ZT order by NBXH--这里返回@intRowCount条纪录,@intRowCount保存了返回记录集中最大的那一条,也就是我们特定页的第一条纪录号SET ROWCOUNT @pagesize --返回@pagesize条纪录,类似top @pagesize 
    print @intBeginID
    select * from SH_QYBASE_ZT where NBXH>=@intBeginID order by NBXHSET ROWCOUNT 0 --返回系统设置
      

  20.   

    上面漏了一点,完整的分页代码。如果你在ASP中直接使用而不是用存储过程,你可以使用Top n代码下面的SET ROWCOUNT n语句:
    declare @pagesize int --每页纪录数
    declare @reccounts int --数据库总的纪录数
    declare @pagecounts int --根据每页纪录数和数据库总的纪录数返回的总页数
    declare @intBeginID int --特定页的第一条(最小)纪录
    declare @intRowCount int --临时变量
    declare @currentpage int --当前页select @pagesize=10 --每页10条纪录
    select @currentpage=5 --设置当前页
    select @reccounts=count(1) from Procurement_Requisition --返回所有纪录数
    if @reccounts/@pagesize*@pagesize=@reccounts
      set @pagecounts=@reccounts/@pagesize  --返回总页数
    else
      set @pagecounts=@reccounts/@pagesize+1 --返回总页数set @intRowCount=(@currentpage-1)*@pagesize+1 --特定页的第一条(最小)纪录在所有纪录中的位置(使用了order by)SET ROWCOUNT @intRowCount
    select @intBeginID=pr_no from Procurement_Requisition order by pr_noSET ROWCOUNT @pagesize
    print @intBeginID
    select * from Procurement_Requisition where pr_NO>=@intBeginID order by pr_noSET ROWCOUNT 0
      

  21.   

    使用使用recordset的PageSize,AbsolutePage,PageCount属性分页
    要注意recordset打开的时候要有
    set rst=recordset.open sql,conn,1,3
    传递的只是指针,而不是实际的数据!
    几十万条记录没有问题的!
      

  22.   

    TO sweet(阿甘) :
    谢谢你,你的方法可能无法解决实际问题,用户有不同的查询条件,数据库又会变,不可能所有的查询都预先转换成静态页面,另外转换成静态页而会花费很多时间,如果你仔细考虑,就会发现你的设计无法达到要求
    to _1_(阿呆)(大冬瓜) 
    谢谢你,你的方法太理想化了,一数据一定会删除,第二SYBASE 的IDENTITY可能是不连续的,第三 即使连续,按其它字段排序时 IDENTITY字段也毫无用处
    to Rock_Guan(Rock) 
    你说的方法具体如何实现(用ADO分面的没有办法的)你能具体一点告诉我吗?
    to mosqutio() 
    会快很多吗?系统又多一个没用的字段,我测试好象没有快多少
    to hydnoahark(诺亚方舟) 
    如果能让数据库只返回50条记录,当然是最快的,可是用户可能用不同的字段作查询条件,可是多个字段的组合查询,所以用存储过程比较困难,
    很讨厌SYBASE 不支持 动态生成的SQL语句,并且没有象ORACLE 的ROWNUM 及SQL SERVER 的TOP N功能
    TO superjs(真剑神) 
    你的方法 与hydnoahark(诺亚方舟)开始的相法一致 以下是我的测试例子。    SqlString = "SELECT * FROM SH_QYBASE_ZT"    
        
        DataRecord.Open SqlString, DataConnect, adOpenKeyset,3
        If Not DataRecord.EOF Then
            DataRecord.PageSize = 50        
            DataRecord.AbsolutePage = 200
        End If
        i = 1
        Do While Not DataRecord.EOF And i < 50
            i = i + 1
            DataRecord.MoveNext
        Loop
        共有记录10160条  费时 15.04秒   
        DataRecord.Open SqlString, DataConnect, adOpenForwardOnly, adLockReadOnly
        DataRecord.Move 10000
        do ..loop 
        共有记录10160条  费时 7.20秒   
      所以我敢断定你没有任何的测试  几万、几十万条记录更没有可能!会让你等死掉
      

  23.   

    DataRecord.Open SqlString, DataConnect, adOpenKeyset,3
        有一个是server的属性,就是数据库打开方式的是服务器的那种,好像要快一些!
    还有,我觉得你的select语句有问题,你能不能拆分呢??还有你的数据库页没有按照索引的方式,这样是很慢的!!7秒也差不多!!
      

  24.   

    我一般是保存上一页的max key,向前翻在SQL语句中where用上一页的max key,向后翻在SQL语句中用本页的max key,每次只取10条。 排序的情况下max key可能为组合key.
    另外,我一般设置max record count 为100,不管用户界面得到的from, to 是多少。
      

  25.   

    SqlString = "SELECT * FROM SH_QYBASE_ZT "后面就没有东西了???比如说索引,排序,等之类的东西了??要是能有几个子句来完成一些东西,也许会快的!!你要是直接打开的话我认为就全部打开记录集了,这样坑定会慢的,
    我想你是不是可以这样,定义变量,记录打开数据库位置,取消剩余的数据表,不使用他们,当用户需要使用的时候,从新加载,从上一次的最末尾开始,然后重复过程?
      

  26.   

    试试
    rs.AbsolutePage = intPage
    PageRecords = rs.GetRows(PageSize, adBookCurrent)
      

  27.   

    rs.AbsolutePage = intPage
    PageRecords = rs.GetRows(PageSize, adBookCurrent)
      

  28.   

    TO tiger315(): 
     rs.GetRows 是可以缩短时时间,但费时最长是的rs.AbsolutePage = intPage
    你可以看看我上面的回复
    TO jacklondon(jacklondon) 
    用户翻页不一定是按1234顺序而可能是 1,100,300
    TO shanle(西北人)
    我ADO用的CursorLocation=adUseServer,
    现在的数据仅是测试就1万多条,实现上数据库有400万条以上,不管你附加什么条件返回的数据集都有可能超过1万条记录
      

  29.   

    to tiger315() 
    非常感谢,如果你用rs.AbsolutePage = intPage 哪你打开数据集的方式不能是仅向前至少为adKeyset 类型,这类型是取得打开数据的所有Key记录指针,1000记录不明显如果是10万条记录肯定会够你受的,如果同时有20人打开此页哪更慢说不定会死掉
    请你试一试查询结果有1万多条记录的浏览速度,
    THX
      

  30.   

    我的不是adKeyset类型,而是adOpenForwardOnly,你可能很奇怪,但我用的方法是每次用
    户点击下一页或指定页面时,都重新建立ADO连接,另外重新生成记录集,记录集用上面的
    函数重新定位返回2维数组,完成后关闭记录集,释放连接。所以我对ADO的使用是动态的。
      

  31.   

    这个问题就象实际中的计算机一样,CPU快了,内存快了,总线也要上去,但愿能有更好的
    软总线出现。
      

  32.   

    另外你使用的实际上的OLEDB+ODBC连接等于多了一层,大概SYBASE从来没有OLEDB 
    PROVIDER(我没关心过),所以上面的连接效率就成问题(ODBC本身效率不是很高),这可
    能也是限制你的一个原因。