日期:2014-05-20  浏览次数:20770 次

请教关于c#读写6万条数据时的优化问题?
各位高手,麻烦了.我公司的数据库是sqlserver2000的,有一张表(bookings)中目前有6万多条数据,因为查询的时候速度太慢了,所以想要其中一些数据移到同一数据库中的别一张表(bookings_bak)中,移动时只要在bookings中留4万条数据,另外两万条就移动到bookings_bak中.我是这样写的,先从bookings中读取一条,再写入bookings_bak中,然后删除bookings中的那条数据,现在的问题时,这样在操作的时候,我看了一下cpu的利用率到100%了,具体是sqlserver.exe这个进程使用了100%的cpu,我想请教各位:
(1)怎么样才能不让他对cpu的占用率这么高?我对写入数据的时间没要求,一个小时或是两个小时完成这个操作也没关系,因为我一天只执行一次.
(2)我最先做的时候,是一次性读取全部的数据,然后在一条一条的写入,请问这样和我读一条写一条比较其来,那种在cpu的占用率上讲低一点?我感觉应该是前一种读取好一点,因为一次性读取只要对数据库请求一次就够了,而读一条写一条的方式,我就要差不多要请求2万次的数据库.

------解决方案--------------------
数据库,不建立索引?
------解决方案--------------------
方法1. 先把符合条件需要备份的数据一次性地读到RecordSet中,然后程序从RecordSet中读取数据插入到备份表中。
方法2. 用一个SQL语句就可以搞掂了。

6万条记录太小意思了,强烈建议楼主优化索引。
------解决方案--------------------
SQL code

/*
建立结构如下的分区表:
Userid int --用户ID
reason int --变更原因
money int --财富
updatetime datetime --更新时间
*/
/*
按照更新时间分区建立分区函数如下
*/
create partition function ChangeLogPF_updatetime (datetime)
as range right for values(
'20030201','20030301','20030401',
'20030501','20030601','20030701',
'20030801','20030901', '20031001',
'20031101','20031201');

/*
按照更新时间分区建立分区
*/
create partition scheme ChangeLogPS_updatetime
as partition ChangeLogPF_updatetime
all to([primary]);
/*
跟据分区函数和分区方案建立分区表
*/
Create table MOney_change_log(
userid int,
reason int,
money int,
updatetime datetime
)on ChangeLogPS_updatetime(updatetime)

/*
跟据分区函数和分区方案建立分区索引
*/
Create index idx_userid_reason on Money_Change_Log(userid,reason)
on ChangeLogPs_updatetime(updatetime)

/*
插入测试数据
userid reason money updatetime
1000 1 100 2003-01-01 11:00:00.000
1000 1 200 2003-01-31 13:23:00.000
1000 1 -50 2003-02-01 23:59:59.000
1000 1 -50 2003-03-01 00:00:00.000
*/
/*
查询各分区中的行的数量
*/
select $partition.ChangeLogPF_updatetime(updatetime),COUNT(*)
from MOney_change_log
group by $partition.ChangeLogPF_updatetime(updatetime)

/*

合并分区

*/

Alter partition ChangeLogPF_Updatetime() Marge Range('20030201')

说明:删除分区'20030201'并把数据移入下一个分区中

/*

新建分区

*/

Alter Partition SCHEM ChangeLogPS_updatetime NEXT USED [primary]

Alter partition ChangeLogPF_Updatetime() SPLIT Range('20040101')

------解决方案--------------------
大容量复制用sqlbulkcopy


create index xx on table (你要查询的字段)



------解决方案--------------------
你的数据Transfer应用应该做成后台进程的模式。如果有字段能够区分时间的先后,可以用Top XXX的方式一次读取一定数量的记录来进行移动的操作。甚至可以自己监测CPU的使用情况和内存的使用情况而在服务器“不忙”的情况下来实施Transfer工作。曾经写过一个类似的,在MS SQL Server, My SQL和Oracle等主流的数据库上都表现不错。
------解决方案--------------------
(1)怎么样才能不让他对cpu的占用率这么高?我对写入数据的时间没要求,一个小时或是两个小时完成这个操作也没关系,因为我一天只执行一次. 

不要 一次 读1条, 一次操作 1000条 会快很多, 

一次读一条 所有的资源 都浪费 在 建立数据库连接 读数据 关闭连接 这些上面了,
------解决方案--------------------
6万条记录查询就慢,你是不是看看服务器配置?或者是你的查询语句太过复杂?用 sql 查询分析器看看。你把两万条移走意义不大吧。

我的数据库都有一百多万条数据了,查询也不见得慢。

如果非得把那两万条记录移走,那直接用sql语句吧,不要用 ado.net。

SQL code

-- delete from bookings_bak
insert into bookings_bak select * from bookings where --条件--
delete from bookings where --条件--

------解决方案--------------------
楼主 我给你提供3个思路 
1.建立索引(6W条其实可以不建)
2.使用存储过程执行操作
3.使用触发器

有疑问 CSDN 联系
------解决方案--------------------
1、建立索引,查询肯定会快。
2、优化查询语句不要select * from table
3、如果一定要a表导入b表,用一条语句就可以了select ... a into b,保证表结构一致,最好启用事务控制。
------解决方案--------------------
1)top 200条,写入,删除,休息1秒,再重复....时间长点,但是,不会cpu 100%