在access中采用sql和absoluteposition两种方式产生随机记录的速度比较

O、我所知道至少有2种access产生随机记录的办法

方法1、采用sql查询随机排序,形如

    objCon.execute("select * from tblTable order by rnd(-" & rnd&")"

方法2、先读取全表,然后采用absoluteposition随机定位

    objRst.open "tblTable",objCon,3,3,2

    for i=1 to N

       objRst.absolutePosition=fix(rnd*objRst.recordCount)+1  'abpos以1开头

       objRst("xxxx")......

    next

 

O、这两种方法各有优劣

   方法1、需要先由sql对全表排序,初始话时间较长,但是一次读取即可,通过设置cachsize,可能全部缓存

   方法2、无需对复杂查询排序,初始化时间短,但读取全表后再处理,由于不可能把全表全部缓存,每次设置absoluteposition都要重新读数据库。

 

O、有限测试

     我对这两种方法进行了简单的测试,测试目标为一个结构为5000条记录的TABLE[id,strValue]的简单数据库,反复1000次每次随机生成1000条记录,经测试,在adCmdTable下产生随机读取数据,方法1在速度上大约较2快1倍以上。测试log如下。

 

---------------Rnd by sql----------------
2008-8-30 11:44:54/0
2008-8-30 11:44:57/50
2008-8-30 11:44:59/100
2008-8-30 11:45:02/150
2008-8-30 11:45:04/200
2008-8-30 11:45:07/250
2008-8-30 11:45:09/300
2008-8-30 11:45:12/350
2008-8-30 11:45:14/400
2008-8-30 11:45:17/450
2008-8-30 11:45:19/500
2008-8-30 11:45:21/550
2008-8-30 11:45:24/600
2008-8-30 11:45:26/650
2008-8-30 11:45:29/700
2008-8-30 11:45:31/750
2008-8-30 11:45:34/800
2008-8-30 11:45:36/850
2008-8-30 11:45:39/900
2008-8-30 11:45:41/950
2008-8-30 11:45:44/1000
---------------Rnd by Position----------------
2008-8-30 11:45:44/0
2008-8-30 11:45:49/50
2008-8-30 11:45:54/100
2008-8-30 11:45:59/150
2008-8-30 11:46:04/200
2008-8-30 11:46:10/250
2008-8-30 11:46:15/300
2008-8-30 11:46:20/350
2008-8-30 11:46:25/400
2008-8-30 11:46:30/450
2008-8-30 11:46:36/500
2008-8-30 11:46:41/550
2008-8-30 11:46:46/600
2008-8-30 11:46:51/650
2008-8-30 11:46:56/700
2008-8-30 11:47:01/750
2008-8-30 11:47:07/800
2008-8-30 11:47:12/850
2008-8-30 11:47:17/900
2008-8-30 11:47:22/950
2008-8-30 11:47:27/1000

O、结论

 对于结构简单的查询,采用sql随机较好

 

附测试代码:

  1. Option Explicit 
  2. Const DB_NAME="test.mdb"    '数据库名
  3. Const DB_RECORD_SIZE=5000   '数据库中记录数
  4. Const TEST_SIZE=1000            '从重复测试的次数
  5. Const TEST_RECORD_SIZE=1000   '从数据库中随机读取的记录数
  6. '创建数据库,仅在第一次时调用
  7. Sub createDb()
  8.     Dim objAdc,objCon,objFo
  9.     Dim strCon
  10.     Set objFo=CreateObject("scripting.filesystemobject")
  11.     If objFo.fileExists(DB_NAME) Then objFo.deleteFile(DB_NAME)
  12.     strCon="provider=microsoft.jet.oledb.4.0; data source=" & DB_NAME
  13.     Set objAdc=CreateObject("adox.catalog")
  14.     Set objCon=objAdc.create(strCon)
  15.     objCon.Execute "CREATE TABLE tblTest"&_
  16.                             "(lngID COUNTER(1,1) PRIMARY KEY,"&_
  17.                             "strValue TEXT(20) )"
  18.     Dim i_
  19.     For i_=0 To DB_RECORD_SIZE-1
  20.         objCon.execute "INSERT INTO tblTEST (strValue) VALUES ('" & "[" &  i_  & "]"   & "')"
  21.     Next 
  22.     If IsObject(objCon) Then 
  23.         If objCon.State<>0 Then objCon.close 
  24.         Set objCon=Nothing 
  25.     End If 
  26.     Set objAdc=Nothing 
  27.     Set objFo=Nothing 
  28.     MsgBox "Db created."
  29. End Sub 
  30. '添加记录到文件
  31. Sub appendLog(strName,strData)
  32.     Dim objTs
  33.     Set objTs=CreateObject("scripting.filesystemobject").openTextFile(strName,8,True)
  34.     objTs.writeLine strData
  35.     objTs.close
  36. End Sub 
  37. '========================= 
  38. '首先测试选取10000
  39. Sub main()
  40.     Dim objCon,objRst
  41.     Dim i,j,k,a,b
  42.     Dim strSql
  43.     Randomize 
  44.     Set objCon=CreateObject("adodb.connection")
  45.     objCon.open "provider=microsoft.jet.oledb.4.0; data source=" & DB_NAME
  46.     'test1
  47.     appendLog "log.txt","---------------Rnd by sql----------------"
  48.     For i=0 To TEST_SIZE
  49.         Set objRst=objCon.execute("select top " & TEST_RECORD_SIZE & " * from tblTest order by rnd(" & Rnd & "-lngId)")
  50.         Do While Not( objRst.bof Or objRst.eof)
  51.             a=objRst("strValue")
  52.             objRst.moveNext
  53.         Loop 
  54.         objRst.close 
  55.         '每隔50次测试记录一次时间
  56.         If i Mod 50  =0 Then appendLog "log.txt",Now() & "/" & i 
  57.     Next 
  58.     Set objRst=Nothing 
  59.     'test 2
  60.     appendLog "log.txt","---------------Rnd by Position----------------"
  61.     Set objRst=CreateObject("adodb.recordset")
  62.     For i=0 To TEST_SIZE
  63.         objRst.open "tblTest",objCon,3,3,2
  64.         For j=0 To TEST_RECORD_SIZE-1
  65.             k=Fix(objRst.RecordCount*rnd)+1
  66.             objRst.AbsolutePosition=k
  67.             a=objRst("strValue")
  68.         Next 
  69.         objRst.close 
  70.         '每隔50次测试记录一次时间
  71.         If i Mod 50  =0 Then appendLog "log.txt",Now() & "/" & i 
  72.     Next 
  73.     objCon.close 
  74.     MsgBox "main end"
  75. End Sub 
  76. main

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值