数据库效率
测试用表:4列,一列为int类型,2列varchar,1列char
添加
往数据库里添加数据目前测试了3个方案
1. 根据数据生成sql语句,直接插入
2. 采用sql传参数的方式插入
3. 采用DataTable更新的方法
测试结果:
在插入5000条记录的时候,方案1和方案2的事件都在2.3s~2.4s,方案1比方案2略快一点,方案3事件在12s上下
从代码的角度上来看,如果可以预知要存储的数据里不带单引号,用方案1还可以再加快一点点数据。不过我倾向使用方案2。
测试代码:
方案1:直接生成sql语句
StringBuilder strSql=new StringBuilder();
strSql.Append("insert into andString(");
strSql.Append("ID, string1,string2,string3");
strSql.Append(")");
strSql.Append(" values (");
strSql.Append(""+model.ID.ToString()+",");
strSql.Append("'"+model.string1.Replace("'", "''") +"',");
strSql.Append("'"+model.string2.Replace("'", "''") +"',");
strSql.Append("'"+model.string3.Replace("'", "''") +"'");
strSql.Append(")");
DbManagerSQL.ExecuteSql(strSql.ToString());
方案2:传参数
StringBuilder addstrSql=new StringBuilder();
addstrSql.Append("insert into andString(");
addstrSql.Append("ID,string1,string2,string3)");
addstrSql.Append(" values (");
addstrSql.Append("@ID,@string1,@string2,@string3)");
SqlParameter[] parameters = {
new SqlParameter("@ID", SqlDbType.Int,4),
new SqlParameter("@string1", SqlDbType.VarChar,200),
new SqlParameter("@string2", SqlDbType.VarChar,2000),
new SqlParameter("@string3", SqlDbType.Char,20)};
parameters[0].Value = model.ID;
parameters[1].Value = model.string1;
parameters[2].Value = model.string2;
parameters[3].Value = model.string3;
DbManagerSQL.ExecuteSql(addstrSql.ToString(),parameters);
方案3:DataTable更新
DataRow row = dt.NewRow();
row["ID"] = model.ID;
row["string1"] = model.string1;
row["string2"] = model.string2;
row["string3"] = model.string3;
dt.Rows.Clear();
dt.Rows.Add(row);
DbManagerSQL.UpdateTable(dt,tempSql);
查询
测试用表:表为添加时的测试用表,表内有30000条记录
测试结果:
1. 用select top 1方案比用 select 方案在查单条记录时候数据要快很多目前测试的比例是1:2
2. Select * 和 select 完整列名,就目前的测试结果来看时间比较接近,大约为1:0.8
3. 从DataSet里取数据比从DataTable里取数据要快很多,基本上是快一倍,这点很是让人纳闷,包括我在sql查询返回DataSet后只返回DataSet的table[0]回去,效率也还是一样的慢,估计问题是出在前台从DataSet取数据的代码经过编译器特别优化了
测试代码:
DataSet取数据代码:
DataSet ds=DbManagerSQL.Query(strSql.ToString(),parameters);
if(ds.Tables[0].Rows.Count>0)
{
model.ID = (int)ds.Tables[0].Rows[0]["ID"];
model.string1=ds.Tables[0].Rows[0]["string1"].ToString();
model.string2=ds.Tables[0].Rows[0]["string2"].ToString();
model.string3=ds.Tables[0].Rows[0]["string3"].ToString();
return model;
}
else
{
return null;
}
DataTable取数据代码:
DataTable dt=DbManagerSQL.QueryTable(strSql.ToString(),parameters);
if(dt.Rows.Count>0)
{
model.ID = (int)dt.Rows[0]["ID"];
model.string1=dt.Rows[0]["string1"].ToString();
model.string2=dt.Rows[0]["string2"].ToString();
model.string3=dt.Rows[0]["string3"].ToString();
return model;
}
else
{
return null;
}
多线程并发数据库访问效率:
测试环境:还是用上面的表,采用直接插入Sql语句方式添加数据,每个线程在测试时插入3次,每次插入1000条数据。底层的数据库访问采用2种访问方式,一个是为每次连接创建一个数据库连接, 另外一个是所用数据库访问都采用同一个连接,每次访问时用线程互斥的进行使用。网络采用100M交换机组网的公司网络。
测试结果:
数据库与测试程序在同一台电脑
单连接 |
多连接 | |||
时间 |
cpu |
时间 |
cpu | |
10 |
4s |
100% |
3~4 |
100% |
20 |
8~9 |
100% |
20~24 |
5% |
30 |
13~15s |
100% |
20~24 |
5% |
50 |
24~27 |
100% |
28~30 |
25% |
70 |
35~39 |
100% |
37~43 |
40% |
数据库与测试程序不在同一台电脑
线程 |
单连接 |
|
多连接 |
| ||
时间 |
cpu |
网卡 |
时间 |
cpu |
网卡 | |
10 |
12s |
10% |
5% |
4 |
5% |
13% |
20 |
25s |
10% |
5% |
11~13 |
5% |
8% |
30 |
32~38s |
15% |
5% |
19~20 |
5% |
9% |
50 |
55~65 |
15% |
5% |
24~27 |
15% |
11% |
70 |
80~90 |
20% |
5% |
29~32 |
40% |
13% |
从测试的数据来看单连接和多连接并不能说那一个更好,只能说要根据实际应用的情况来选择实际连接方式,因为目前还没有使用连接池的C#代码,所以没有针对连接池方案进行测试。
在并发条件下优化查询最佳的方案应该是优化数据库
在数据库与应用程序分离的时候进行并发查询操作,发现提高查询数据的瓶颈不在应用程序,而是在数据库。
字符串效率
在生成数据sql语句的时候,要将多个参数合并到一个sql语句中,常用的方法有4个
1. 字符串直接相加
2. Replace
3. Format
4. Stringbuffer类
反正不管怎么比较方案1的字符串直接相加法绝对绝对是慢的,但也是最容易理解的,建议能用其他方法替换就尽量不用。
方案2和方案3一般用来替换sql语句里的参数,不适用于字符串连接。如果只是需要替换一个字符串,用Replace比较合适,速度比Format快20%,如果要替换2个以上的字符串就只使用Format方法
用方案1和方案2连接字符串,效率相差可以达到20倍,连接的字符串越多StringBuffer越显示出它的效率来,不过可惜的是在连接5个以下字符串的时候,他们的效率差不多。