日期:2014-05-16  浏览次数:20999 次

sql server 大数据量并发插入问题
开发了一个设备采集监控系统。其中设备数据项有2000多个,保存在sql server2008中。存储方案是针对每个设备创建一个单独的数据库,里面建立多个数据表,把数据项分表存储。在主数据库中提供插入数据存储过程,将传入的数据插入到对应数据库中。
测试中发现,使用ado连接数据库,当有60个线程同时插入60个设备的数据,同时开30个线程进行查询。每个线程都采用独立的连接,查询的时候将数据表设置为nolock。但是还是会出现查询超时已过期问题。想问一下这是由于sql server本身处理不过来导致的,还是ado的问题。
同时单独运行一个线程插入时速度还可以,但60个线程同时插入的时候,单个线程的插入速度就降到原来的1/20。所有线程调用的是同一个存储过程,但是插入数据库不同。
------解决方案--------------------
当有60个线程同时插入60个设备的数据,同时开30个线程进行查询。每个线程都采用独立的连接,查询的时候将数据表设置为nolock。但是还是会出现查询超时已过期问题。

你看下这个时候数据库资源吃紧不?
插入慢,应该是插入的时候有阻塞的,同表的insert相互之间阻塞。
------解决方案--------------------
另外,看看系统的等待情况:



--等待类型统计
select top 10
wait_type,            --等待类型
waiting_tasks_count,  --

wait_time_ms,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
order by wait_time_ms desc

------解决方案--------------------
60个设备也就是60个数据库通过一个存储过程同时插入数据啊,太恐怖了,估计内存资源也会很吃紧的
------解决方案--------------------
如果一个服务器上面建的数据库太多,并且同时插数据,相互间应该会竞争资源的,
不知道有没有那位大牛试过,同一台服务器上面一台数据库和n台数据库,针对单库来说性能会差多少
------解决方案--------------------
这个如果你钱不缺的话,多级汇总,避免过于集中插入
------解决方案--------------------
1.如果业务允许,建议想办法读写分离。
2.insert能不能想办法做出批量的。就是一次插入多条数据,而不是多次插入每次插入一条数据。
3.这么多线程一起插入,即使内存cpu都能吃得消,估计IO不一定能扛得住
------解决方案--------------------
1.用BULK INSERT插入
2..NET使用长连接
3.数据库模式设置为简单模式
4.删除表上的所有索引,只剩主键聚集索引,该主键最好是自增长列
5.服务器阵列是RAID10吗?
6.如果是SQL2014可以用最新的延迟写入机制就是DELAY或使用内存表,IO能提高10倍没问题。

------解决方案--------------------
扯,分为多个数据库,应该是在一台SVR上吧,那么就是多个日志文件,你让磁盘磁头乱跳,效率会高么??
ADO默认执行时间是30秒,什么任务执行要超过30秒?
这个超时属客户端行为,非SQL SERVER服务行为
正确设计是正道
------解决方案--------------------
为什么要用同一个存储过程呢?
既然是不同的连接就调用该连接的数据库中的那个存储过程了
同一台机器上哪怕用存储过程了但跨数据库了效率还是有影响的
------解决方案--------------------
都分数据库了,为什么还要使用同一个存储过程来往不同数据库里写数据?

插入数据的话会在page的级别产生IX锁,这个是不影响查询的。

如果表有聚集索引,会在key级别产生X锁,所谓X锁就是排他锁。
也就是说如果事务T在某个页面或者表上加了X锁,那么别的事务是不能够访问这个页面或者表的。
------解决方案--------------------
引用:
Quote: 引用:

60个设备也就是60个数据库通过一个存储过程同时插入数据啊,太恐怖了,估计内存资源也会很吃紧的

我觉得单个存储过程被多个连接并发调用,只要使用的资源不存在排他锁问题,应该可以。不过cpu却是占用很高,几乎满了。我主要是在想是由于cpu处理不过来导致的,还是由于并发插入存在锁的问题。因为我并发插入的数据是在不同的数据库中,只是调用的存储过程是同一个。


运行下面的语句,看看有没有阻塞的问题:
select *
from sys.sysprocesses
where blocked <> 0

------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

60个设备也就是60个数据库通过一个存储过程同时插入数据啊,太恐怖了,估计内存资源也会很吃紧的

我觉得单个存储过程被多个连接并发调用,只要使用的资源不存在排他锁问题,应该可以。不过cpu却是占用很高,几乎满了。我主要是在想是由于cpu处理不过来导致的,还是由于并发插入存在锁的问题。因为我并发插入的数据是在不同的数据库中,只是调用的存储过程是同一个。


运行下面的语句,看看有没有阻塞的问题:
select *
from sys.sysprocesses
where blocked <> 0