Foxtable(狐表)用户栏目专家坐堂 → [求助]外部数据存储效率问题


  共有3283人关注过本帖树形打印复制链接

主题:[求助]外部数据存储效率问题

帅哥哟,离线,有人找我吗?
chnfo
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2239 积分:18446 威望:0 精华:0 注册:2011/11/26 20:21:00
[求助]外部数据存储效率问题  发帖心情 Post By:2021/1/8 13:37:00 [只看该作者]

1、使用ACCESS做外部数据库
2、有些表使用了表达式列,包括但不限于逻辑列、字符串列
3、使用了论坛上的保存函数

    If strlist.Count > 0 Then   ‘strlist指的是对数据做增删改的脚本
        Dim cmd As new SQLCommand()
        cmd.ConnectionName = “外部数据连接名“
        Try
            cmd.BeginTransaction() '开启事务
            
            For Each s As String In strlist
                cmd.CommandText = s
                cmd.ExecuteNonQuery()
            Next
            cmd.Commit() '提交事务
        Catch ex As Exception '如果出错
            cmd.Rollback() '则回滚事务
            'MessageBox.Show(ex.Message, "错误",MessageBoxButtons.OK,MessageBoxIcon.Error)
        End Try
        
        tables("XX").DataTable.BaseTable.AcceptChanges()   '提交修改
    End If

现在的问题是:
(1)因为使用了一些表达式列(有些设了公式,有些没有),在项目运行过程中,难免会对表达式赋值,而一旦对表达式赋值,就会被判定为当前行修改过,导致SQL脚本的update部分会将这些列误认为数据列有改变而去后台执行
(2)实测17000行数据的时候,事务提交用时在40秒左右(即使只是表达式列有赋值而数据列没有变化,也会如此)。

解决路径可能有
(1)判断当前行是否有改变,是否能做到只判断数据列,表达式列无视?如果可以,SQL脚本行就可以少很多
(2)即使1可行,还得从事务提交的处理效率上想办法。如果17000行作为一个事务提交,排队执行,效率显然不高;如果有更多的数据,甚至是十万、百万级别,SQL脚本逐行处理,那效率可能更低了。有什么好的办法吗?

 回到顶部
帅哥哟,离线,有人找我吗?
有点蓝
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110443 积分:562081 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2021/1/8 13:55:00 [只看该作者]

判断是否表达式列:
if DataTables("订单").DataCols("金额").Expression > "" then msgbox("表达式列")

对于access来说已经是最高的效率了,如果嫌事务长,可以自行分批处理,比如每遍历有10000行更改就保存提交一次

 回到顶部
帅哥哟,离线,有人找我吗?
chnfo
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:九尾狐 帖子:2239 积分:18446 威望:0 精华:0 注册:2011/11/26 20:21:00
  发帖心情 Post By:2021/1/8 14:04:00 [只看该作者]

(1)我知道怎么去判断是否为表达式列。
我是说能不能做到判断当前行是否有修改时,只以数据列是否有修改为标准去判断(不论表达式列的值有没有变化,都忽略掉)
(2)分批处理能提高效率?试了一下,好象不咋滴。是用下面这样的方式分批?或者用异步函数(如果用异步函数,怎么整呢)?
            For i as integer = 0 to strlist.count - 1
dim s as string = strlist(i)
                cmd.CommandText = s
                cmd.ExecuteNonQuery()
if i mod 1000 = 0 orelse i = strlist.count - 1 then 
            cmd.Commit() '提交事务
            end if 
            Next
(3)论坛上的帖子中,外部数据如果用SQL,不也得通过事务处理?
[此贴子已经被作者于2021/1/8 14:15:24编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
有点蓝
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:超级版主 帖子:110443 积分:562081 威望:0 精华:9 注册:2015/6/24 9:21:00
  发帖心情 Post By:2021/1/8 14:24:00 [只看该作者]

1、这个是.net内部自行控制的,外部没有办法控制判断

2、每一批都有单独创建和提交事务,理论上是差不多的,复制都是也要插入同样多的数据,好处是可以减少事务锁表的时间,让其它用户可以使用这个表

3、不管什么数据库都只能这样,如果是新增有些数据库会提供批量处理的方法:http://www.foxtable.com/bbs/dispbbs.asp?BoardID=2&ID=147288&replyID=&skin=1

 回到顶部