ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: lbpp

[分享] 一句话让程序运行速度提高了几百倍(recordset的CursorLocation属性)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2009-6-19 13:55 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖已被收录到知识树中,索引项:ADO技术
cnn.CursorLocation = adUseClient

是快了!,只是为什么这种快不是默认的?
有限制条件吗?

请其它朋友也测试与指点下!

TA的精华主题

TA的得分主题

发表于 2009-6-19 14:20 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
cn.CursorLocation = adUseClient
这个快是在读取数据的时候快还是更新数据的时候快?
如果我是连接局域网的access,如下,也能用么?
Set cn = New ADODB.Connection
cn.Open "provider=Microsoft.jet.OLEDB.4.0;data source=" & "\\mainpc\share\db.mdb"
还有rs.CursorLocation = adUseClient什么时候放

如果我读取两张表的话是不是要放两个rs.CursorLocation = adUseClient???
rs.CursorLocation = adUseClient
  Set rs = New ADODB.Recordset
  With rs
   .Open "SELECT * FROM 表1 where " & "yonghu" & "='" & yhm & "'", cn, 1, 1, adCmdText

end with
rs.CursorLocation = adUseClient
  Set rs = New ADODB.Recordset
  With rs
   .Open "SELECT * FROM 表2 where " & "材料码" & "='" & clm & "'", cn, 1, 1, adCmdText

end with

[ 本帖最后由 yf_992258 于 2009-6-19 14:23 编辑 ]

TA的精华主题

TA的得分主题

发表于 2009-6-20 09:47 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
请教楼主几件事:
1\楼主用的是外网?,因为我也是用SQL2000,一般来说,更新1000多条数据去不了你说的那个时间,我基本都是在局网!如你是在外网,那么你的经历对我以后可能的外网使用就有了很大的指导意义了.

2\你所用的游标是批量更新,,是先取出一个记录集,更新了记录集的数据,然后批量更新数据库,而本人的使用局网是全部是用一条条数所用addnew添加,这个方法与你的方法,的异同在那里?是否真的是我的方法更不适用于外网?我有一张表7536行*21列用现时的方法是27S,

我会试用你的方式,只是到时还得再指教才行

我想试下.可不知从何下手,你这个修改,与新增有差别?

另外你的那个rstSaveFile是如何出来的?
可否新增的也在本机上搞一个这样的文件再批量更新?

现在我的做法里面有好多的新增内容,且在数据库中判断一条增加一条,同时更新库中的三个表,

也就是类似一个工号,的东东要改变,则库里的三张表都得同时改变,第天的量不少,如果可以改进速度,则是很值得高兴的事,烦请指点.

多谢

[ 本帖最后由 sunsoncheng 于 2009-6-20 11:03 编辑 ]

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-6-20 18:17 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
原帖由 sunsoncheng 于 2009-6-19 13:55 发表
cnn.CursorLocation = adUseClient

是快了!,只是为什么这种快不是默认的?
有限制条件吗?

请其它朋友也测试与指点下!


CursorLocation用来指定ADO临时表存放的位置,默认情况下临时表存放于服务器端,而对临时表的操作也不是通过ADO直接操作,而是提交给OLE DB或数据库来完成,也就是说每一个对临时表的操作都要通过第三者来完成。我不知道我的分析是否正确,因为我找到影响速度的代码就是filter属性,开始以为是未排序的原因,而当我想把recordset保存成文件,以便上传到论坛里给大做测试,然而发现当保存成文件后,排序对于速度的影响可以忽略不计,因此才注意到是CursorLocation的设置问题,至于我前面分析速度慢的是否真的是网络原因(我使用的也是内网),还是通过OLE DB或数据库来完成操作引起的,我也只是猜测。

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-6-20 18:34 | 显示全部楼层
这个快是在读取数据的时候快还是更新数据的时候快?
如果我是连接局域网的access,如下,也能用么?

我认为这个东西有点类似于我们写邮件,如果我们是通过foxmail这样的邮件客户端来写邮件,那么保存基本不需要时间,因为邮件直接保存在本机中,但如果我们登录到WEB邮箱里写邮件,当点击保存时数据量大的时候会花费很长时间,因为需要把数据上传到服务器端。当我们将数据读入recordset时,ADO会生成一个临时表,默认情况下,这个表存放在服务器端,本地只存放很少量的数据,而当指定CursorLocation = adUseClient时,这些数据会保存在本地,由ADO直接对临时表进行操作,减少了中间环节,我分析这是提高速度的关键。这个参数只是对ADO的设置,我认为应该与数据库类型无关,只是ADO在处理中的方法不同。

Set cn = New ADODB.Connection
cn.Open "provider=Microsoft.jet.OLEDB.4.0;data source=" & "\\mainpc\share\db.mdb"
还有rs.CursorLocation = adUseClient什么时候放

CursorLocation属性在recordset或connection打开时为只读,关闭时为可读写,因此要设置CursorLocation值必须在open之前。


如果我读取两张表的话是不是要放两个rs.CursorLocation = adUseClient???

如果两个rs是基于同一个connection,那么只要设置connection的CursorLocation就可以了,默认情况下RS会继承connection的CursorLocation值。从你的示例中来看只要用这个方法就可以了。

rs.CursorLocation = adUseClient
  Set rs = New ADODB.Recordset
  With rs
   .Open "SELECT * FROM 表1 where " & "yonghu" & "='" & yhm & "'", cn, 1, 1, adCmdText

end with
rs.CursorLocation = adUseClient
  Set rs = New ADODB.Recordset
  With rs
   .Open "SELECT * FROM 表2 where " & "材料码" & "='" & clm & "'", cn, 1, 1, adCmdText

end with

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-6-20 19:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
1\楼主用的是外网?,因为我也是用SQL2000,一般来说,更新1000多条数据去不了你说的那个时间,我基本都是在局网!如你是在外网,那么你的经历对我以后可能的外网使用就有了很大的指导意义了.

其实我用的也是内网,至于是否是因为网速度引起的,这只是我猜测的几个原因,并不一定正确,我但我想如果所有的操作都需通过OLE DB或数据库来完成的话,这中间肯定存在一个频繁的ADO与OLE DB或数据库之间的转换过程,而如果临时表存放在本地的话,由ADO直接操作,这样当然会更快。
我使用的也是SQL SERVER 2000,环境应该和你的差不多,方便的话发一个你的代码让我看看,我找找原因看,说不定我前面的所有分析都是错的,呵呵。

2\你所用的游标是批量更新,,是先取出一个记录集,更新了记录集的数据,然后批量更新数据库,而本人的使用局网是全部是用一条条数所用addnew添加,这个方法与你的方法,的异同在那里?是否真的是我的方法更不适用于外网?我有一张表7536行*21列用现时的方法是27S,

采用批更新的原因是不用频繁读写数据库,可以先对ADO的临时表完成所有的操作后,一次性完成对数据库的访问,我认为在对数据记录修改量在的情况下,批更新应该效率更高。你提到你的示例中更新用时27秒,我想问一下,如果你直接在数据库的后台进行操作,这些数据量,对于一个数据库来说应该根本感觉不到压力,一下子就完成了,以前有人说过对于ORACLE来说,可能上亿条的记录操作可能才有感觉,虽然我没用过ORACLE,但我日常中在后台直接对SQL SERVER进行的操作,基本都是秒杀,除了一些表间连接很多的操作,才会有点感觉。

我想试下.可不知从何下手,你这个修改,与新增有差别?

另外你的那个rstSaveFile是如何出来的?


至于rstSaveFile文件的产生方法是这样的。
ADO去持把recordset保存到文件中,这样就可以脱离服务器而直接操作数据,也就是脱机工作。当联机后,可以直接用updatebatch一次性把数据进行同步。这个功能非常实用,实现也很方便。


'将打开的recordset保存到c:\rstSaveFile
rsGzb.Save "c:\rstSaveFile"


'打开保存的文件rstSaveFile
rs.Open "c:\rstSaveFile", , adOpenStatic, adLockBatchOptimistic, adCmdFile


'连机
'先建立cn
rs.ActiveConnection=cn
updatebatch

TA的精华主题

TA的得分主题

发表于 2009-6-20 20:25 | 显示全部楼层
感觉上还是有点问题!
就是大批量或频繁的数据变动,尤其别人的变动会引起你的变化时,
比如我们生产一样东西,一个工序生产了100个,但的它的下工序出了两个废品

这时会有人在生产100个的工序中输入补生产的两个数,也就是这个单子本来要生产100个已完成了的,现在却是未完成 的了。

如果正好在你的临时表变动时别人作了这个修正,而你的还以是原来的100(而你实际是102才行),就会产生错误

所以个人以为,这种锁定的方式或更新的方式是不是存在危机?
当你在很多产品在生产时,很多机子在用时,这都是有可能的吧,

只是讨论下,我的代码得等回公司再上传上来看看

我现的做法基本上都是取出再转为数组,再在本机运行。尽量减少到数据库存取数据的次数。

TA的精华主题

TA的得分主题

发表于 2009-6-20 20:35 | 显示全部楼层
'打开保存的文件rstSaveFile
rs.Open "c:\rstSaveFile", , adOpenStatic, adLockBatchOptimistic, adCmdFile

用了三年,还不知道这个用法,受教了。

修改这个文件,就用普能修改数据库的方法,还有,还是这个新增问题,如何在这个文件上新增?

因为取出来是空的记录能保存在文件头吗?

一切都要等星期一再试,试了行的话可就惨了,要重新评估下速度,必要时,以前的程序全部要修改,唉

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-6-21 11:20 | 显示全部楼层
原帖由 sunsoncheng 于 2009-6-20 20:35 发表
'打开保存的文件rstSaveFile
rs.Open "c:\rstSaveFile", , adOpenStatic, adLockBatchOptimistic, adCmdFile

用了三年,还不知道这个用法,受教了。

修改这个文件,就用普能修改数据库的方法,还有,还是这个 ...


recordset的open方法可以看做是对数据源的访问,无论是我们常用的连接到数据库,执行SQL查询还是从文件中打开其实都是将数据源的数据存放入Recordset,,接下来的操作那都是一样的。修改这个文件只要使用recordset提供的相应的方法就可以了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2009-6-21 11:22 | 显示全部楼层
原帖由 sunsoncheng 于 2009-6-20 20:25 发表
感觉上还是有点问题!
就是大批量或频繁的数据变动,尤其别人的变动会引起你的变化时,
比如我们生产一样东西,一个工序生产了100个,但的它的下工序出了两个废品

这时会有人在生产100个的工序中输入补生产的两 ...


其实对于如你这样多用户系统,只需要关注锁定方式,至于是用update还是updatebatch就要看哪个更合理了。

向你介绍本书,《ADO编程技术》,微软出版社出的,现在已经绝版了,原来在书店看到过,但没买,后来就找不到了,在淘宝上找到一 本二手的,买了。非常不错的一本工具书,详细介绍了ADO的各个细节,其实我们实际运用中很多的东西可以直接使用ADO来完成,而现在大部分的应用只限于通过ADO把数据读入到EXCEL,然后用SQL语句通过ADO写回到数据库中,并没有真正使用ADO提供的功能。

刚搜了一下,现在好像chinaPub上还有得买,有兴趣可以去买一本。呵呵。给个链接http://www.china-pub.com/1906

[ 本帖最后由 lbpp 于 2009-6-21 11:34 编辑 ]
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-20 04:33 , Processed in 0.031593 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表