ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] access升迁SQL后的执行效率,如何优化?

[复制链接]

TA的精华主题

TA的得分主题

发表于 2012-12-19 15:24 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
我的access有3个表,其中Table1_sql,Table2_sql,各有数十万条记录,已升迁到SQL,Tabel3_local在本机。

当我用以下两种方法运算的时候,产生了很大的效率差异:
方法一 .     3个表直接关联运算,或本地表做子查询,都很慢,长达数分钟,不管本地表的数据有多少。

方法二.    只关联Table1_sql,Table2_sql,本地表Tabel3_local的值取出来,再放到SQL语句,执行时基本可以忽略时间。

这两种方法,得到的结果是一样的。方法一是否用了access自带的数据引擎,只把SQL上的表作为外部表,导致大量的数据传输?  而方法二是否用SQL数据引擎,只返回查询结果?
求解惑!

另,如果我的理解正确,该如何解决这个问题?如果先用 ADODB.Recordset调入本地表,是否会达到方法二的效率?如何实现,是逐条调用Recordset的数据,还是用数组变量,如何把recordset的值赋给数组?

谢谢!

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-12-20 14:10 | 显示全部楼层
本帖最后由 shepdog 于 2012-12-20 14:47 编辑

没有人可以讨论一下吗?

我查了网络资料,貌似SQL语句不支持用数组变量。
可以把本地表Tabel3_local的内容变为字符串变量,作为查询语句的条件,如下以t_SO表为例:
Private Sub Command2_Click()
Dim str As String
Dim a As Long
Dim Rssdb As New adodb.Recordset
Rssdb.Open "select [WBS NO] from t_SO;", CurrentProject.Connection, adOpenKeyset, adLockOptimistic
If Rssdb.EOF Then
Else
    Rssdb.MoveFirst
     For i = 0 To Rssdb.RecordCount - 1
           str = str & """" & Rssdb(0) & ""","
     Rssdb.MoveNext
      Next i
    '两端加上括号,截去最后一个“,”号
     a = Len(str)
     str = "(" & Left(str, a - 1) & ")"
End If
Debug.Print a, str
Rssdb.Close
Set Rssdb = Nothing
End Sub

后面,在查询SQL时,in 后面加 str变量,就可以了。

TA的精华主题

TA的得分主题

发表于 2012-12-21 02:52 | 显示全部楼层
如果数据量大的情况,一般都采用第二种方式,若干循环得到相关参数变量,形成一定的SQL语句,传给服务器SQL,等回传结果就行了,速度一般是运算的复杂度和结果集的大小,我也采用2楼的方式,这样服务器的安全性也能够提升(做成MDE,代码ADO连接)

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-12-21 09:22 | 显示全部楼层
本帖最后由 shepdog 于 2012-12-21 09:25 编辑
Renco 发表于 2012-12-21 02:52
如果数据量大的情况,一般都采用第二种方式,若干循环得到相关参数变量,形成一定的SQL语句,传给服务器SQL ...

我上面说的是一个条件的select或delete句型。
假如说,是Update、Insert 句型,上面的方法不能用啊,怎么办呢?
比如说,Access本地表有Col1,Col2两个字段,其中Col1等于SQL表的主键,要把Col2字段的值更新到SQL的表,怎么实现呢?

TA的精华主题

TA的得分主题

发表于 2012-12-21 13:21 | 显示全部楼层
rs.open (本地表)
rs.movefirst
str=""
For i = 0 To rs.RecordCount - 1
           str = str & "Update 服务器表 set 服务器表字段='" & rs(【本地表字段Col2】) & "' Where 服务器表.Col1='" & rs(【本地表字段Col1】)  & "';" & chr(13)
  rs.MoveNext
Next i
'最终形成一个逐条更新的语句
Server服务器ADO.connection.execute   str


以上是思路,有些参数及声明,请相应完善即可

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-12-21 15:37 | 显示全部楼层
本帖最后由 shepdog 于 2012-12-21 15:38 编辑
Renco 发表于 2012-12-21 13:21
rs.open (本地表)
rs.movefirst
str=""

你说的方法,我有想过,但是没有测试过。
我担心,这样会不会由于反复的与服务器交换数据,变得比较慢?

TA的精华主题

TA的得分主题

发表于 2012-12-21 19:15 | 显示全部楼层
不会,你的connection不要用一下就关闭,可以在登录使用程序时就连接上,全局声明,等整个程序关闭时才退出,事实上还很快

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-21 21:53 | 显示全部楼层
本帖最后由 shepdog 于 2013-1-21 21:55 编辑
Renco 发表于 2012-12-21 13:21
rs.open (本地表)
rs.movefirst
str=""

你好!
我现在遇到麻烦了,要求助你了!
我在Access有个连接到SQL的ODBC链接表,假设表名为t_sql,我可以做出来一段字符串:
str="update t_sql set col1=value(0);
       update t_sql set col1=value(1);
       ..............
       update t_sal set col1=value(n);

那么,我可以直接 Docmd.runsql str 吗? 还是要先用ADODB.Connection 打开连接?可以是我不知道t_sql表的connectionstring

请帮帮忙,谢谢!

TA的精华主题

TA的得分主题

发表于 2013-1-22 00:58 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
在ACCESS里有个隐藏的系统表 MSysObjects
里面有放着链接表的connect,你可以利用一下,
Docmd.runsql str 是本地执行,所以是无法执行你上面的语句的,除非你用传递查询(须要设置ODBC)
ADO方式,与ODBC方式是不同的连接打开方式 的,打开后用execute来执行你的语句就行了

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-1-22 12:01 | 显示全部楼层
本帖最后由 shepdog 于 2013-1-22 12:08 编辑
Renco 发表于 2013-1-22 00:58
在ACCESS里有个隐藏的系统表 MSysObjects
里面有放着链接表的connect,你可以利用一下,
Docmd.runsql st ...

十分感谢你的回复!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-17 03:29 , Processed in 0.034162 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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