首页 新闻 会员 周边

c# 向数据库插入数据的困惑

0
悬赏园豆:50 [待解决问题]

同样的代码,向数据库插入10000条记录,在winfrom项目上使用52秒,在ConsoleApplication项目上使用30秒,而在测试项目下只要5秒,请问Visual studio在这几种情况下为何差别这么大。
数据库是本地数据库。我并不是想大家优化我的代码,因为如果大数量插入数据用sqlbulkcopy更好,只是想知道为什么在不同项目下会有如此大的差别,因为不同项目下的代码都是一样的

代码如下:

          Stopwatch sw = new Stopwatch();
            sw.Start();
            string ConnString = "Data Source=.;Initial Catalog=xfl_mis;Integrated Security=True";
            string sql = @"INSERT INTO Insure(VehicleCustomNo,PlateNumber ,InsuranceNumber,InsureCompany,InsuranceON, InsureBeginDate,InsureEndDate,InsureType,InsuredAmount ,AmortizeBeginDate,AmortizeEndDate) values
                        ('A12','粤1' ,'SN123','panan','2010-01-01','2010-01-01', '2010-01-01','2加强险',1000 ,'2010-01-01','2010-01-01')";
            for (int i = 0; i < 10000; i++)
            {
                using (SqlConnection conn = new SqlConnection(ConnString))
                {
                    SqlCommand cmd = new SqlCommand();
                    cmd.Connection = conn;
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandText = sql;
                    conn.Open();
                    cmd.ExecuteNonQuery();
                    if (conn.State != ConnectionState.Closed)
                        conn.Close();

                }
            }

            MessageBox.Show("插入总耗时:" + sw.ElapsedMilliseconds); 

数据表:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Insure]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Insure]
GO

CREATE TABLE [dbo].[Insure] (
[InsureId] [int] IDENTITY (1, 1) NOT NULL ,
[VehicleCustomNo] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[PlateNumber] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[InsuranceNumber] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[InsureCompany] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
[InsuranceON] [datetime] NULL ,
[InsureBeginDate] [datetime] NULL ,
[InsureEndDate] [datetime] NULL ,
[InsureType] [varchar] (10) COLLATE Chinese_PRC_CI_AS NULL ,
[InsuredAmount] [decimal](10, 0) NULL ,
[AmortizeBeginDate] [datetime] NULL ,
[AmortizeEndDate] [datetime] NULL 
) ON [PRIMARY]
GO

玉箫子的主页 玉箫子 | 初学一级 | 园豆:150
提问于:2011-02-09 15:01
< >
分享
所有回答(4)
0

你这样做很明显是有问题的

每执行一条,数据库打开一回,又关闭一回,这样当然影响了录入10000条的速度,而且也增加了系统开销,浪费了时间。

建议组合成一个sql语句,一次性执行,你可以测试下,时间上应该会少许多。

 

                    conn.Open();  //打开
                    cmd.ExecuteNonQuery();
                    if (conn.State != ConnectionState.Closed)
                        conn.Close();//关闭

不停的打开,关闭,打开,关闭,这就是问题

jerry-Tom | 园豆:4077 (老鸟四级) | 2011-02-09 15:08
我把using去掉了,只用一个SqlConnection了,现在的情况是代码完全相同的情况下的不同项目向数据库写入数据的区别,请不要在代码优化下讨论。 现在的情况是winform项目下和测试项目下的时间差十倍,所以才拿出来讨论一下。代码如下: Stopwatch sw = new Stopwatch(); sw.Start(); string ConnString = "Data Source=.;Initial Catalog=xfl_mis;Integrated Security=True"; string sql = @"INSERT INTO Insure(VehicleCustomNo,PlateNumber ,InsuranceNumber,InsureCompany,InsuranceON, InsureBeginDate,InsureEndDate,InsureType,InsuredAmount ,AmortizeBeginDate,AmortizeEndDate) values ('A12','粤1' ,'SN123','panan','2010-01-01','2010-01-01', '2010-01-01','2加强险',1000 ,'2010-01-01','2010-01-01')"; SqlConnection conn = new SqlConnection(ConnString); SqlCommand cmd = new SqlCommand(); cmd.Connection = conn; cmd.CommandType = CommandType.Text; cmd.CommandText = sql; conn.Open(); for (int i = 0; i < 10000; i++) { cmd.ExecuteNonQuery(); } if (conn.State != ConnectionState.Closed) conn.Close(); sw.Stop(); Console.WriteLine("插入总耗时:" + sw.ElapsedMilliseconds); Console.ReadKey();
支持(0) 反对(0) 玉箫子 | 园豆:150 (初学一级) | 2011-02-09 15:28
0

winform中应该有线程、界面刷新等因素。

至于那个测试项目时间更短的原因,猜测不到。

mywork | 园豆:475 (菜鸟二级) | 2011-02-10 09:31
0

Integrated Security=True

信任连接 相较于 UserID\PSW身份认证连接,稍慢!这点你可以动手测试一下

应该加上事务 - cmd.Transactio 速度会快很多的...

 

对于大批量插入数据 应该使用SqlBulkCopy



Kabayashi | 园豆:128 (初学一级) | 2011-02-10 23:19
0

我觉得问题可能出在界面和数据库缓冲池上,你可以测试一下在Winform和Console里面都新建一个线程单独处理,结果使用委托的方式显示出来。

.NET默认应该是使用数据库缓冲池的,我个人认为在测试项目和其他的里面,.NET的数据库连接缓冲池大小不一样,你可以看看都关闭缓冲池试试。

归真 | 园豆:605 (小虾三级) | 2011-02-15 09:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册