C# 加载数据的时间非常长。大量的数据。C语言中的SQL查询

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对象具有以下代码

我在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的请求都需要花费大量的时间才能完成。我看到这个循环运行得很好,但肯定没有得到优化

那么,我怎样才能提高这个过程的速度呢

一次获取更多数据-因为您预先知道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(','));