是因为表中数据量太大的原因吗?(表记录超过110万条)

时间:2022-05-26 23:25:39
前段时间使用“JAVA + SQL SERVER 2000 标准版 + jdbc for sql server 2000”做了一套短信SP端的系统。

系统主要分两部分:
1、与移动、联通短信网关通信的系统
2、用来进行数据查询、维护的后台管理系统,基于WEB,使用ASP编写。

系统一负责短信的接收和下发,数据库操作非常频繁。下发到手机的信息,全部存放在 cmpp_outbox 表里,系统一使用触发、定时相结合的方式,从 cmpp_outbox 里取得需要下发到手机的数据,让后更新cmpp_outbox中对应记录的标记(例如是否已下发、尝试的次数等)。网关收到数据时,回应接收是否成功的数据包,系统一收到回应数据包时,也更新cmpp_outbox表;短信发送成功或失败时,短信网关也会给系统一发送状态报告,系统一根据状态报告,更新cmpp_outbox。
所以,系统一对于cmpp_outbox的更新极为频繁。
为了提高效率,我在cmpp_outbox上加了5~6个索引。

系统二负责汇总cmpp_outbox中的数据,根据下发短信的记录,计算出某一时间段内的费用,相对于系统一的操作,系统二的操作是非常耗时的,一般需5~10秒的时间。


本来两系统一直运行正常,前几天系统二突然出现问题,汇总的结果远远超过实际值(实际值可以根据以往数据估算出来),并且肯定是不正确的,最让人不解的是,同一个查询语句,运行多次的汇总结果不相同!


请问这是不是因为系统一更新操作太过频繁,导致系统二的耗时查询返回的结果不正确?应该如何解决这个问题?升级到企业版能解决这个问题吗?
请专家指教,万分感谢!


因为系统二希望实时的查询计费,所以定时导出数据再做查询的方案暂且不考虑。

7 个解决方案

#1


更新太频繁,的话索引多了反而不好,你的填充因子要够大。

#2


速度,影响它的因数太多了,且数据量越大越明显。
1、存储
   将硬盘分成NTFS格式,NTFS比FAT32快,并看你的数据文件大小,1G以上你可以采用多数据库文件,这样可以将存取负载分散到多个物理硬盘或磁盘阵列上。

2、tempdb
   tempdb也应该被单独的物理硬盘或磁盘阵列上,建议放在RAID 0上,这样它的性能最高,不要对它设置最大值让它自动增长

3、日志文件
   日志文件也应该和数据文件分开在不同的理硬盘或磁盘阵列上,这样也可以提高硬盘I/O性能。

4、分区视图
   就是将你的数据水平分割在集群服务器上,它适合大规模OLTP,SQL群集上,如果你数据库不是访问特别大不建议使用。

5、簇索引
   你的表一定有个簇索引,在使用簇索引查询的时候,区块查询是最快的,如用between,应为他是物理连续的,你应该尽量减少对它的updaet,应为这可以使它物理不连续。

6、非簇索引
   非簇索引与物理顺序无关,设计它时必须有高度的可选择性,可以提高查询速度,但对表update的时候这些非簇索引会影响速度,且占用空间大,如果你愿意用空间和修改时间换取速度可以考虑。

7、索引视图
   如果在视图上建立索引,那视图的结果集就会被存储起来,对与特定的查询性能可以提高很多,但同样对update语句时它也会严重减低性能,一般用在数据相对稳定的数据仓库中。

8、维护索引
   你在将索引建好后,定期维护是很重要的,用dbcc showcontig来观察页密度、扫描密度等等,及时用dbcc indexdefrag来整理表或视图的索引,在必要的时候用dbcc dbreindex来重建索引可以受到良好的效果。

不论你是用几个表1、2、3点都可以提高一定的性能,5、6、8点你是必须做的,至于4、7点看你的需求,我个人是不建议的。

#3


你可以另加一张表以存放返回状态报告.因你cmpp_outbox 表是要保存下来的,到你备份回备份服务器后在匹配!计费的工作也最好放在后台来!毕竟状态报告不是一下就能回来的.

#4


其实我现在面对的不是速度的问题,无论select还是update速度都是很快的,问题是什么原因导致了相同的select语句,运行多次返回的结果却不相同?前提是这些数据肯定都是固定的了,绝对没有进行任何更新。

#5


你还是要仔细查一下sql语句。

#6


应该是sql语句的问题吧,select distinct 一下看有没有重复的记录在你的结果表里。

#7


give me your sql

#1


更新太频繁,的话索引多了反而不好,你的填充因子要够大。

#2


速度,影响它的因数太多了,且数据量越大越明显。
1、存储
   将硬盘分成NTFS格式,NTFS比FAT32快,并看你的数据文件大小,1G以上你可以采用多数据库文件,这样可以将存取负载分散到多个物理硬盘或磁盘阵列上。

2、tempdb
   tempdb也应该被单独的物理硬盘或磁盘阵列上,建议放在RAID 0上,这样它的性能最高,不要对它设置最大值让它自动增长

3、日志文件
   日志文件也应该和数据文件分开在不同的理硬盘或磁盘阵列上,这样也可以提高硬盘I/O性能。

4、分区视图
   就是将你的数据水平分割在集群服务器上,它适合大规模OLTP,SQL群集上,如果你数据库不是访问特别大不建议使用。

5、簇索引
   你的表一定有个簇索引,在使用簇索引查询的时候,区块查询是最快的,如用between,应为他是物理连续的,你应该尽量减少对它的updaet,应为这可以使它物理不连续。

6、非簇索引
   非簇索引与物理顺序无关,设计它时必须有高度的可选择性,可以提高查询速度,但对表update的时候这些非簇索引会影响速度,且占用空间大,如果你愿意用空间和修改时间换取速度可以考虑。

7、索引视图
   如果在视图上建立索引,那视图的结果集就会被存储起来,对与特定的查询性能可以提高很多,但同样对update语句时它也会严重减低性能,一般用在数据相对稳定的数据仓库中。

8、维护索引
   你在将索引建好后,定期维护是很重要的,用dbcc showcontig来观察页密度、扫描密度等等,及时用dbcc indexdefrag来整理表或视图的索引,在必要的时候用dbcc dbreindex来重建索引可以受到良好的效果。

不论你是用几个表1、2、3点都可以提高一定的性能,5、6、8点你是必须做的,至于4、7点看你的需求,我个人是不建议的。

#3


你可以另加一张表以存放返回状态报告.因你cmpp_outbox 表是要保存下来的,到你备份回备份服务器后在匹配!计费的工作也最好放在后台来!毕竟状态报告不是一下就能回来的.

#4


其实我现在面对的不是速度的问题,无论select还是update速度都是很快的,问题是什么原因导致了相同的select语句,运行多次返回的结果却不相同?前提是这些数据肯定都是固定的了,绝对没有进行任何更新。

#5


你还是要仔细查一下sql语句。

#6


应该是sql语句的问题吧,select distinct 一下看有没有重复的记录在你的结果表里。

#7


give me your sql