C# 加载数据的时间非常长。大量的数据。C语言中的SQL查询
我在C WPF中有以下代码C# 加载数据的时间非常长。大量的数据。C语言中的SQL查询,c#,sql,wpf,oledb,C#,Sql,Wpf,Oledb,我在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对象具有以下代码
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的请求都需要花费大量的时间才能完成。我看到这个循环运行得很好,但肯定没有得到优化
那么,我怎样才能提高这个过程的速度呢
一次获取更多数据-因为您预先知道ID列表,而不是逐个查询项。如果您想要具有键1、2、3、4的项,那么不要执行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;
}
通过这种方式,您可以通过计数获得CP值,这样可以减少数据量
请阅读有关使您的代码更安全的内容
不要一个接一个地获取CP,而是执行单个查询,选择整个表,然后在表中迭代。这将大大提高速度。 您的查询将是:
"SELECT * FROM CP";
然后做一些类似的事情:
List<string> cps = table_name.AsEnumerable()
.Select(r=> r.Field<string>("...."))
.ToList();
一个经常使用Access DBs的家伙的建议是:始终使用参数化查询。它将为您保存大多数不兼容的类型错误。尤其是在处理日期…时,您可以尝试在字典中缓存整个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也有大约10万个项目,它将需要兆字节的RAM。修改:
因此,这会将所有id以逗号分隔的形式传递给函数,并且它只会在SQL查询中执行一次,因此数据库连接只会打开一次。其余的逻辑应该插入到存储过程中,因为SP也比普通SQL查询快得多。将节省90%的时间。希望这能奏效。对于初学者,您可以使用1、3、5、7、8、9中的where id,您真的需要选择所有100k吗?如果你的数据库中有id,你可以做一个更快的连接。@juergen-d数据库有pairs id,CP。我需要知道我列表中每个元素的CP来进行统计计算。你代码中的id来自哪里?如果也来自数据库,那么您可以直接加载CP。您可以将获取的结果缓存在缓存中,以避免再次向RDBMS请求这些结果;或者甚至可以将整个CP表缓存在一个字典中。那么为什么不将文件中的ID加载到DB中,然后在那里进行连接呢。或者,如果内存使用不是问题所在,并且可以将完整的表加载到程序中,那么@gnqz回答是什么?我认为我将按照@dmitry bychenko的建议将表缓存到字典中,谢谢你的回答@费尔南多加列戈费尔南德斯谢谢你,我很高兴能帮上忙。另外,请随意接受我的回答:
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;
}
}
var strId=string.empty;
lista.Foreach(x=>
{
strId+=","+x.itemKey;
});
var cp = consulta.returnCP(strId=strId.TrimStart(','));