我在C#WPF中有以下代码
ConsultaDB consulta = new ConsultaDB();
foreach (var item in lista)
{
var cp = consulta.returnCP(item.Key);
if (cp.Length != 5)
{
//Some code here with the data returned
}
}
list
是> 100K元素的集合,ConsultaDB
对象具有以下代码:
class ConsultaDB
{
string CP;
OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=CCPP.accdb");
public string returnCP(string id)
{
var comm = conn.CreateCommand();
comm.CommandType = CommandType.Text;
comm.CommandText = "SELECT CP FROM CP WHERE ID='" + id+ "'";
var returnValue = comm.ExecuteScalar();
CP = returnValue.ToString();
return CP;
}
public ConsultaDB()
{
conn.Open();
}
}
这里的问题是对DB的所有请求都需要花费大量时间才能完成。我看到循环运行良好,但肯定没有优化。
那么,我该如何提高这个过程的速度呢?
答案 0 :(得分:2)
不是逐个获取CP,而是执行单个查询,选择整个表,然后在表中进行迭代。它将大大提高速度。 您的查询将是:
"SELECT * FROM CP";
然后执行以下操作:
List<string> cps = table_name.AsEnumerable()
.Select(r=> r.Field<string>("...."))
.ToList();
一个使用Access DB玩过很多的人的建议 - 总是使用参数化查询。它将为您节省大多数不兼容的类型错误。特别是当你使用日期......
答案 1 :(得分:1)
一次获取更多数据 - 因为您事先知道ID列表,而不是逐个查询项目进行一次调用。如果您想要具有键(1,2,3,4)
的项目,那么只需执行一个
SELECT CP FROM CP WHERE ID IN (1,2,3,4)
在C#
代码中,这意味着
public string returnCP(List<string> ids)
{
var comm = conn.CreateCommand();
comm.CommandType = CommandType.Text;
comm.CommandText = string.Format( "SELECT CP FROM CP WHERE ID IN({0})",string.Join(",",ids));
var returnValue = comm.ExecuteScalar();
CP = returnValue.ToString();
return CP;
}
如果您需要大量ID,请求页面请求。如果您需要10,000个ID,那么一次加载所有这些都是低效的 - 最好将数据请求拆分成几个小块。这样他们仍然会加载几百条记录,但不会太多。
如果数据访问仍然是瓶颈并且您经常为同一对象调用它,请考虑使用 cache - 它将允许您更快地访问数据。根据您的体系结构,内存缓存可以使数据访问速度极快。
这是特定于案例的,但如果CP
不是唯一的(读取:对于许多记录来说,它通常是相同的),您也可以使用GROUP
查询
SELECT CP,COUNT(*) FROM CP GROUP BY CP
通过这种方式,您可以获得CP
值,这些值可以减少数据量
请阅读SQL Injection以使您的代码更安全
答案 2 :(得分:1)
您可以尝试在字典中缓存整个CP
表:
class ConsultaDB {
private static Dictionary<String, String> s_Data = new
Dictionary<String, String>();
private static void CoreFeedCache() {
using (OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=CCPP.accdb")) {
using (var comm = conn.CreateCommand()) {
comm.CommandText =
@"select ID,
CP
from CP";
using (reader = comm.ExecuteReader()) {
while (reader.Read()) {
s_Data.Add(Convert.ToString(reader[0]), Convert.ToString(reader[1]));
}
}
}
}
}
static {
CoreFeedCache();
}
public static string returnCP(string id) {
String result;
if (!s_Data.TryGetValue(id, out result))
result = null;
return result;
}
}
如果CP
也包含 100K 项,则需要 MegaBytes 的RAM。
答案 3 :(得分:1)
修改:
var strId=string.empty;
lista.Foreach(x=>
{
strId+=","+x.itemKey;
});
var cp = consulta.returnCP(strId=strId.TrimStart(','));
因此,这将把所有id作为逗号分隔传递给函数,它只会在SQL查询一次执行,因此只会打开一次数据库连接。逻辑的其余部分应插入存储过程中,因为SP再次比普通SQL查询快得多。 90%的时间将被保存。希望这有效。