SQL Server ado 查询超时已过期

时间:2021-04-30 11:09:30
环境:
WIN7+VS2013+SQL Server2008
MFC程序使用ado连接数据库

出现问题:
在删除原表的已备份信息时,会弹出查询超时已过期的对话框。
SQL Server ado 查询超时已过期


问题原因及分析:
    储存结果的表太大了,400W+(正常使用情况不会达到这么高的数量级,这是在极端情况下的数据。已考虑索引,且只是存储一个站点的信息)。表中的数据有多个月的(正常情况下是存储本月和上月的信息,目前才考虑备份表的)。
    在进行备份和删除原表的已备份信息时,删除原表的已备份信息时会弹出查询超时已过期的对话框。(删除了多个月的信息,正常情况应该只有一个信息)
    备份操作是备份上一个月的,删除原表的已备份信息是删除这个月以前的所有的数据

    使用_ConnectionPtr对象进行的备份等操作,相关操作在单独线程中,一个月备份一次,不在乎执行时间长短。
    经过多次尝试,改过许多可能参数,除了修改_ConnectionPtr的CommandTimeout属性外都是在90s左右的时候弹出查询超时已过期对话框。

    我觉得应该就是将查询超时时间设置一个大值(比如200s),就可以解决问题,但是不知道具体方法。希望哪位高手指点一下,多谢!!!

已进行的尝试:
1.网上说的设置超时时间,
sp_configure 'show advanced options', 1      
GO      
RECONFIGURE      
GO      
sp_configure 'query wait', 2147483647      
GO      
RECONFIGURE      
GO
结果是不行

2.设置事务超时
SQL Server ado 查询超时已过期
结果是不行

3.设置_ConnectionPtr属性
pConn->CommandTimeout = 60;
把这个值设置得很大的话,还是弹出查询超时对话框,但是弹出对话框的实际会延长到比CommandTimeout 还稍微大一些的时间以后,还是不行

25 个解决方案

#1


你可以用ssms运行下sql语句,使用prifiler抓取下语句的执行时间看看,实际跑了多长时间

#2


http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客

#3


应用程序对数据库的操作, 一般不应该执行 “大操作” —— 比如你这种 定期删除大量数据的就不合适。
这种定期删除的操作, 应该用SQL Server 的作业来实现, 不会超时, 而且方便查看运行的历史记录。
SQL Server ado 查询超时已过期

#4


如果你一定要用程序来实现, 则可以用循环实现, 每次只删除 1000  条数据, 这样可以保证不会超时, 而且不会引起大日志的问题。
对于不是很重要的库, 可以将库的恢复模式设置为简单, 可以加快删除的速度:
SQL Server ado 查询超时已过期

#5


引用 1 楼 z10843087 的回复:
你可以用ssms运行下sql语句,使用prifiler抓取下语句的执行时间看看,实际跑了多长时间


在ssms上运行相同的语句,备份大概是15s左右(3次平均),删除原表已备份的信息(还包括前几个月的数据,比正常操作量要大一些)大概是38s左右(3次平均)

#6


引用 2 楼 z10843087 的回复:
http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

#7


采用分批次删除的方式实现

#8


引用 3 楼 yenange 的回复:
应用程序对数据库的操作, 一般不应该执行 “大操作” —— 比如你这种 定期删除大量数据的就不合适。
这种定期删除的操作, 应该用SQL Server 的作业来实现, 不会超时, 而且方便查看运行的历史记录。
SQL Server ado 查询超时已过期


一般的应用场景是1分钟或更长时间记录一条数据,某些特定的使用场景可能1秒记录一条数据。如果是1分钟记录一条数据的话,数据量也还好。

之前也是用作业实现备份的。但是产品经理考虑到设置作业对技术支持的要求可能比较高,容易出错,要求用程序实现。

#9


引用 7 楼 yisuylm 的回复:
采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

#10


引用 9 楼 Sunday0508 的回复:
Quote: 引用 7 楼 yisuylm 的回复:

采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

不要挑战数据库的极限, 这种做法很蠢, 没有任何意义。 

一次性大量删除数据库的记录, 属于一个大的事务日志, 缓慢是正常的。
你自己设想一下:
让你把 400万斤 白菜扛到菜市场, 不准出任何错误, 包括不准掉任何一片叶子, 如果出了错就必须重来, 这个过程很简单吗?找这么大一辆车来都不容易!翻车了又如何处理?
换个做法, 400万斤白菜, 每次 1000 斤, 你只需要负责每次不出错就行了, 出了错, 只需要纠正那次的错误即可。

#11


还有我在 #4 的改恢复模式的, 对加快删除很有帮助的, 你可以试试。

#12


引用 6 楼 Sunday0508 的回复:
Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout

#13


可以设置CommandTimeout 的时候,是不是查询时间太久?

#14


引用 12 楼 z10843087 的回复:
Quote: 引用 6 楼 Sunday0508 的回复:

Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout


是CommandTimeout设置为600的。我发现在执行删除原表已备份信息的操作的时候,再用ssms对正在删除的表进行select count(*)操作的时候,会阻塞,直到600s以后。证明ado的SQL操作是一直在执行的。
我把CommandTimeout设为6000,等了一个小时,还是提示超时。应该还是不能直接用ado操作这么大的数据量,不知道为啥,ssms却可以这么操作。

#15


引用 10 楼 yenange 的回复:
Quote: 引用 9 楼 Sunday0508 的回复:

Quote: 引用 7 楼 yisuylm 的回复:

采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

不要挑战数据库的极限, 这种做法很蠢, 没有任何意义。 

一次性大量删除数据库的记录, 属于一个大的事务日志, 缓慢是正常的。
你自己设想一下:
让你把 400万斤 白菜扛到菜市场, 不准出任何错误, 包括不准掉任何一片叶子, 如果出了错就必须重来, 这个过程很简单吗?找这么大一辆车来都不容易!翻车了又如何处理?
换个做法, 400万斤白菜, 每次 1000 斤, 你只需要负责每次不出错就行了, 出了错, 只需要纠正那次的错误即可。


我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

#16


引用 14 楼 Sunday0508 的回复:
Quote: 引用 12 楼 z10843087 的回复:

Quote: 引用 6 楼 Sunday0508 的回复:

Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout


是CommandTimeout设置为600的。我发现在执行删除原表已备份信息的操作的时候,再用ssms对正在删除的表进行select count(*)操作的时候,会阻塞,直到600s以后。证明ado的SQL操作是一直在执行的。
我把CommandTimeout设为6000,等了一个小时,还是提示超时。应该还是不能直接用ado操作这么大的数据量,不知道为啥,ssms却可以这么操作。

难道我没写清楚,是两种超时

#17


引用 15 楼 Sunday0508 的回复:
我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。



#18


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#19


1.如果你在后台执行要多久?
2.pConn->CommandTimeout = 60;这个是前台代码中的设置吗?

#20


引用 17 楼 yenange 的回复:
Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。





的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。

现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

#21


引用 20 楼 Sunday0508 的回复:
Quote: 引用 17 楼 yenange 的回复:

Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。

的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。
现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

这两个操作当然互相有影响。

最好是把两个操作的顺序固定下来, 也就是按顺序依次地先插入、再删除。
这样的效果是最好的。
没有插入、更新操作的影响, 删除多一点也不会卡着。

插入 => 删除 => 插入 => 删除 ……



#22


引用 21 楼 yenange 的回复:
Quote: 引用 20 楼 Sunday0508 的回复:

Quote: 引用 17 楼 yenange 的回复:

Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。

的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。
现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

这两个操作当然互相有影响。

最好是把两个操作的顺序固定下来, 也就是按顺序依次地先插入、再删除。
这样的效果是最好的。
没有插入、更新操作的影响, 删除多一点也不会卡着。

插入 => 删除 => 插入 => 删除 ……





    两个线程同时操作的确是有影响的。

    不启动插入操作线程是备份线程是能够正常执行删除原表已备份的信息的,但是也必须分次数删除,不能一次性删除。网上说的原因:delete操作会被完整记录到日志里,它需要大量空间和时间;如果删除中间发生中断,一切删除会回滚(在一个事务里) ;
    虽然使用ssms能够一次性删除,但是在程序中最好还是分批次删除。

    启动插入操作线程后,备份线程进行删除原表已备份的信息的操作,哪怕两个操作之间加了临界区进行互斥处理,也只能删除一部分,到中间某次删除就会被阻塞导致查询超时已过期,异常的值是DB_E_ABORTLIMITREACHED。认为是sql server死锁的问题,查了半天,也没理出头绪。进行了一些尝试,没有效果。

#23


在网上又查到一种方案,我的实现步骤如下(没有执行插入操作线程,只有备份线程操作表):
1.判断原表中是否存在上上个月的信息,有的话进行下面操作
2.将上上个月的信息从原表中备份到备份表中
3.将上月和本月的信息(本月里面没有多少数据)拷贝到一个中间表中
4.对原表进行truncate操作
5.将中间表的内容再拷会原表

目前按上述在第4步不能执行,会弹出查询超时已过期的问题。屏蔽步骤1、2、3,直接进行第4步可以直接把原表清空,耗时在20ms以内。
按照这种情况,难道是自己阻塞自己,还是别的什么原因?

#24


从网上找了好多方法进行尝试,还是解决不了。还是自己对数据库不太熟悉,都是用到哪才学哪一块,得抽时间系统性的学习一下数据库。

准备换个方法,在插入表的时候就按月份确定表名,这样就可以避免备份操作。

非常感谢 _大约在冬季_、OwenZeng_DBA 两位版主的耐心的解答!

#25


引用 24 楼 Sunday0508 的回复:
从网上找了好多方法进行尝试,还是解决不了。还是自己对数据库不太熟悉,都是用到哪才学哪一块,得抽时间系统性的学习一下数据库。

准备换个方法,在插入表的时候就按月份确定表名,这样就可以避免备份操作。

非常感谢 _大约在冬季_、OwenZeng_DBA 两位版主的耐心的解答!

客气了,别忘记结帖,,有问题都可以到论坛上面来提

#1


你可以用ssms运行下sql语句,使用prifiler抓取下语句的执行时间看看,实际跑了多长时间

#2


http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客

#3


应用程序对数据库的操作, 一般不应该执行 “大操作” —— 比如你这种 定期删除大量数据的就不合适。
这种定期删除的操作, 应该用SQL Server 的作业来实现, 不会超时, 而且方便查看运行的历史记录。
SQL Server ado 查询超时已过期

#4


如果你一定要用程序来实现, 则可以用循环实现, 每次只删除 1000  条数据, 这样可以保证不会超时, 而且不会引起大日志的问题。
对于不是很重要的库, 可以将库的恢复模式设置为简单, 可以加快删除的速度:
SQL Server ado 查询超时已过期

#5


引用 1 楼 z10843087 的回复:
你可以用ssms运行下sql语句,使用prifiler抓取下语句的执行时间看看,实际跑了多长时间


在ssms上运行相同的语句,备份大概是15s左右(3次平均),删除原表已备份的信息(还包括前几个月的数据,比正常操作量要大一些)大概是38s左右(3次平均)

#6


引用 2 楼 z10843087 的回复:
http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

#7


采用分批次删除的方式实现

#8


引用 3 楼 yenange 的回复:
应用程序对数据库的操作, 一般不应该执行 “大操作” —— 比如你这种 定期删除大量数据的就不合适。
这种定期删除的操作, 应该用SQL Server 的作业来实现, 不会超时, 而且方便查看运行的历史记录。
SQL Server ado 查询超时已过期


一般的应用场景是1分钟或更长时间记录一条数据,某些特定的使用场景可能1秒记录一条数据。如果是1分钟记录一条数据的话,数据量也还好。

之前也是用作业实现备份的。但是产品经理考虑到设置作业对技术支持的要求可能比较高,容易出错,要求用程序实现。

#9


引用 7 楼 yisuylm 的回复:
采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

#10


引用 9 楼 Sunday0508 的回复:
Quote: 引用 7 楼 yisuylm 的回复:

采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

不要挑战数据库的极限, 这种做法很蠢, 没有任何意义。 

一次性大量删除数据库的记录, 属于一个大的事务日志, 缓慢是正常的。
你自己设想一下:
让你把 400万斤 白菜扛到菜市场, 不准出任何错误, 包括不准掉任何一片叶子, 如果出了错就必须重来, 这个过程很简单吗?找这么大一辆车来都不容易!翻车了又如何处理?
换个做法, 400万斤白菜, 每次 1000 斤, 你只需要负责每次不出错就行了, 出了错, 只需要纠正那次的错误即可。

#11


还有我在 #4 的改恢复模式的, 对加快删除很有帮助的, 你可以试试。

#12


引用 6 楼 Sunday0508 的回复:
Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout

#13


可以设置CommandTimeout 的时候,是不是查询时间太久?

#14


引用 12 楼 z10843087 的回复:
Quote: 引用 6 楼 Sunday0508 的回复:

Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout


是CommandTimeout设置为600的。我发现在执行删除原表已备份信息的操作的时候,再用ssms对正在删除的表进行select count(*)操作的时候,会阻塞,直到600s以后。证明ado的SQL操作是一直在执行的。
我把CommandTimeout设为6000,等了一个小时,还是提示超时。应该还是不能直接用ado操作这么大的数据量,不知道为啥,ssms却可以这么操作。

#15


引用 10 楼 yenange 的回复:
Quote: 引用 9 楼 Sunday0508 的回复:

Quote: 引用 7 楼 yisuylm 的回复:

采用分批次删除的方式实现


在我自己的电脑上,内存等资源比较充足,所以备份操作能够执行完成,在某台测试的电脑上(内存较小,还运行了别的很多程序),执行备份操作都会超时。

其实比较想知道的是数据库对外部连接的操作时间会不会有超时时间设置,如果把这个值放大的的话,应该能解决所有问题。

不要挑战数据库的极限, 这种做法很蠢, 没有任何意义。 

一次性大量删除数据库的记录, 属于一个大的事务日志, 缓慢是正常的。
你自己设想一下:
让你把 400万斤 白菜扛到菜市场, 不准出任何错误, 包括不准掉任何一片叶子, 如果出了错就必须重来, 这个过程很简单吗?找这么大一辆车来都不容易!翻车了又如何处理?
换个做法, 400万斤白菜, 每次 1000 斤, 你只需要负责每次不出错就行了, 出了错, 只需要纠正那次的错误即可。


我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

#16


引用 14 楼 Sunday0508 的回复:
Quote: 引用 12 楼 z10843087 的回复:

Quote: 引用 6 楼 Sunday0508 的回复:

Quote: 引用 2 楼 z10843087 的回复:

http://blog.csdn.net/yenange/article/details/9292639
参考@yenange的博客


改为用_CommandPtr对象进行操作,CommandTimeout设为600,现象也是一样的。设为600以后大概就是10分钟后弹出查询超时对话框。这个和我尝试3是一样的。

我觉得问题可能是数据库对外部连接的操作时间有一个超时时间设置,问题是怎么设置这个值

有2中超时时间,一个是连接的,一个是命令的 你设置了这个吗 SqlConnection.ConnectionTimeout  还是CommandTimeout


是CommandTimeout设置为600的。我发现在执行删除原表已备份信息的操作的时候,再用ssms对正在删除的表进行select count(*)操作的时候,会阻塞,直到600s以后。证明ado的SQL操作是一直在执行的。
我把CommandTimeout设为6000,等了一个小时,还是提示超时。应该还是不能直接用ado操作这么大的数据量,不知道为啥,ssms却可以这么操作。

难道我没写清楚,是两种超时

#17


引用 15 楼 Sunday0508 的回复:
我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。



#18


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#19


1.如果你在后台执行要多久?
2.pConn->CommandTimeout = 60;这个是前台代码中的设置吗?

#20


引用 17 楼 yenange 的回复:
Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。





的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。

现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

#21


引用 20 楼 Sunday0508 的回复:
Quote: 引用 17 楼 yenange 的回复:

Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。

的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。
现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

这两个操作当然互相有影响。

最好是把两个操作的顺序固定下来, 也就是按顺序依次地先插入、再删除。
这样的效果是最好的。
没有插入、更新操作的影响, 删除多一点也不会卡着。

插入 => 删除 => 插入 => 删除 ……



#22


引用 21 楼 yenange 的回复:
Quote: 引用 20 楼 Sunday0508 的回复:

Quote: 引用 17 楼 yenange 的回复:

Quote: 引用 15 楼 Sunday0508 的回复:

我把操作分成120份,每次删除2W多条。每次操作完后Sleep(2000)(不休眠2s的话,执行到一部分就卡住了,会弹出查询超时,估计是不能请求太过频繁吧)

你这个删除的表有很多人同时在访问吗?
如果是这样,删除太多记录容易引起堵塞, 换成每次只删除 100 条试试。

的确是还有一个连接负责插入数据。根据设置,一般是1分钟,但也可能是1秒,目前以1秒进行测试,数据是24小时不间断的。
现在在往表中插上入数据,即正常工作状态下(测试电脑内存比较紧张,有一些别的程序,模拟实际使用环境),把CommandTimeout 设长以后,可以保证备份表操作,但是删除原表已备份的信息时,会弹出超时已过期,已经把每次删除数据缩减到了216了。出现这个问题是因为插入操作把表锁死了吗?

这两个操作当然互相有影响。

最好是把两个操作的顺序固定下来, 也就是按顺序依次地先插入、再删除。
这样的效果是最好的。
没有插入、更新操作的影响, 删除多一点也不会卡着。

插入 => 删除 => 插入 => 删除 ……





    两个线程同时操作的确是有影响的。

    不启动插入操作线程是备份线程是能够正常执行删除原表已备份的信息的,但是也必须分次数删除,不能一次性删除。网上说的原因:delete操作会被完整记录到日志里,它需要大量空间和时间;如果删除中间发生中断,一切删除会回滚(在一个事务里) ;
    虽然使用ssms能够一次性删除,但是在程序中最好还是分批次删除。

    启动插入操作线程后,备份线程进行删除原表已备份的信息的操作,哪怕两个操作之间加了临界区进行互斥处理,也只能删除一部分,到中间某次删除就会被阻塞导致查询超时已过期,异常的值是DB_E_ABORTLIMITREACHED。认为是sql server死锁的问题,查了半天,也没理出头绪。进行了一些尝试,没有效果。

#23


在网上又查到一种方案,我的实现步骤如下(没有执行插入操作线程,只有备份线程操作表):
1.判断原表中是否存在上上个月的信息,有的话进行下面操作
2.将上上个月的信息从原表中备份到备份表中
3.将上月和本月的信息(本月里面没有多少数据)拷贝到一个中间表中
4.对原表进行truncate操作
5.将中间表的内容再拷会原表

目前按上述在第4步不能执行,会弹出查询超时已过期的问题。屏蔽步骤1、2、3,直接进行第4步可以直接把原表清空,耗时在20ms以内。
按照这种情况,难道是自己阻塞自己,还是别的什么原因?

#24


从网上找了好多方法进行尝试,还是解决不了。还是自己对数据库不太熟悉,都是用到哪才学哪一块,得抽时间系统性的学习一下数据库。

准备换个方法,在插入表的时候就按月份确定表名,这样就可以避免备份操作。

非常感谢 _大约在冬季_、OwenZeng_DBA 两位版主的耐心的解答!

#25


引用 24 楼 Sunday0508 的回复:
从网上找了好多方法进行尝试,还是解决不了。还是自己对数据库不太熟悉,都是用到哪才学哪一块,得抽时间系统性的学习一下数据库。

准备换个方法,在插入表的时候就按月份确定表名,这样就可以避免备份操作。

非常感谢 _大约在冬季_、OwenZeng_DBA 两位版主的耐心的解答!

客气了,别忘记结帖,,有问题都可以到论坛上面来提