连接SLQSever困惑我很久的问题
先看代码如下
Dim mmsConString As String = "Data Source=10.10.2.179;Initial Catalog=DBTEST;Persist Security Info=True;User ID=sa;Password=Chaos2;"
conn = New SqlConnection(mmsConString)
Try
conn.Open()
trans = conn.BeginTransaction()
cmd = New SqlCommand()
cmd.Connection = conn
For cnt As Integer = 1 To 1
Dim sbCmd As New StringBuilder
sbCmd.Append(" INSERT INTO jk_users(user_login,user_pass,user_nicename,user_email")
sbCmd.Append(" ,user_url,user_registered,user_activation_key,user_status,display_name) ")
sbCmd.Append(" VALUES (@user_login,@user_pass,@user_nicename,@user_email,@user_url, ")
sbCmd.Append(" @user_registered,@user_activation_key, @user_status,@display_name) ")
cmd.CommandText = sbCmd.ToString()
cmd.Parameters.Add(New SqlParameter("@user_login", 10))
cmd.Parameters.Add(New SqlParameter("@user_pass", "user_pass"))
cmd.Parameters.Add(New SqlParameter("@user_nicename", "user_nicename"))
cmd.Parameters.Add(New SqlParameter("@user_email", "user_email"))
cmd.Parameters.Add(New SqlParameter("@user_url", "user_url"))
cmd.Parameters.Add(New SqlParameter("@user_registered", Date.Now))
cmd.Parameters.Add(New SqlParameter("@user_activation_key", "user_activation_key"))
cmd.Parameters.Add(New SqlParameter("@user_status", 1))
cmd.Parameters.Add(New SqlParameter("@display_name", "display_name"))
For ii As Integer = 0 To 100
cmd.Parameters.Add(New SqlParameter("VENDOR_QTY" & ii, 0))
Next
cmd.Transaction = trans
swTime.Start()
cmd.ExecuteNonQuery()
swTime.Stop()
Next
trans.Commit()
Catch ex As Exception
trans.Rollback()
Finally
Dim sCost As String = swTime.Elapsed.TotalMilliseconds
conn.Close()
End Try
TABLE如下
CREATE TABLE [dbo].[jk_users](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[user_login] [varchar](60) NOT NULL,
[user_pass] [varchar](64) NOT NULL,
[user_nicename] [varchar](50) NOT NULL,
[user_email] [varchar](100) NOT NULL,
[user_url] [varchar](100) NOT NULL,
[user_registered] [datetime] NOT NULL,
[user_activation_key] [varchar](60) NOT NULL,
[user_status] [int] NOT NULL,
[display_name] [varchar](250) NOT NULL,
CONSTRAINT [PK_jk_users] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
问题就是那段红色的字,没有任何意义只是为了撑大SqlCommand。
如果那段红色的字注释掉那么 cmd.ExecuteNonQuery()所用的时间是200毫秒,反之执行时间只要4毫秒.
如果循环次数超过1000的话也需要200毫秒,如果循环次数只有30的话也需要200多毫秒,
给我的感觉是
SqlCommand.size < X1 OR SqlCommand.size Between X2 and X3 时候性能很高。
两者相差了50倍的速度,实在不能理解。
在这一年的测试中,我排除了 Parameters 时候设置参数属性,大小的原因,以及写法的原因。
如果这次再找不到解决问题,我估计要彻底放弃Parameters的写法,改用sql拼凑写法(太麻烦了要考虑一大堆注入式攻击)。所以这里拜求各位给我出出主意到底是什么原因造成这么怪异的情况,按道理SqlConnection说默认的8K足够用了,再说为什么添加了100个无用的参数后性能反而提高了,实在不理解。
这里先谢谢,谢谢,再谢谢了。
[解决办法]
我就想问你了!
你插入一条有10个字段的数据,和你插入有30个字段的数据效率一样吗?
你插入一条数据和你同时插入30条数据,请问效率一样吗?
有一点可以说是绝对,就是插入的数据越少或者字段越少,速度肯定越快。
但是,如果数据量大的时候,想要效率尽可能的高,怎么办。这得靠写代码的人怎么去优化,如:何时加索引、怎么优化脚本、如何批量处理数据,都是写代码的人去考虑的!
[解决办法]
楼主我测试了,实时证明他是随机的,跟你连接数据库那一刻的压力有关系
你加这个循环无关大雅,量不大没影响,量大了肯定慢
为了证明我试过,贴代码
SqlConnection conn = new SqlConnection(sqlstr);
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "insert into tempGolden values(@resname,@stkcode,@stkname)";
cmd.Parameters.Add("@resname", "xxx");
cmd.Parameters.Add("@stkcode", "111111");
cmd.Parameters.Add("@stkname", "mmmmm");
DateTime t1 = DateTime.Now;
cmd.ExecuteNonQuery();
DateTime t2 = DateTime.Now;
Response.Write("不加参数耗时:" + (t2 - t1).TotalMilliseconds);
}
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "insert into tempGolden values(@resname,@stkcode,@stkname)";
cmd.Parameters.Add("@resname", "xxx");
cmd.Parameters.Add("@stkcode", "111111");
cmd.Parameters.Add("@stkname", "mmmmm");
for (int i = 0; i < 100; i++)
{
cmd.Parameters.Add("@test" + i, "1111");
}
DateTime t3 = DateTime.Now;
cmd.ExecuteNonQuery();
DateTime t4 = DateTime.Now;
Response.Write("加参数耗时:" + (t4 - t3).TotalMilliseconds);
}
