加载数据的时间很长。大量数据。 SQL C# 查询
A very long time of loading data. Large Amount of Data. SQL queries in C#
我在 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();
}
}
这里的问题是所有对数据库的请求都需要花费大量时间才能完成。我看到循环运行良好,但肯定没有优化。
那么,我怎样才能提高该过程的速度?
一次获取更多数据 - 因为您提前知道 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;
}
页面请求,如果你需要很多id。如果您需要 10,000 个 ID,一次加载所有 ID 的效率会很低——最好将数据请求分成几个小块。这样他们仍然可以加载几百条记录,但不会太多。
如果数据访问仍然是一个瓶颈,并且您经常为相同的对象调用它,请考虑使用 缓存 - 它可以让您更快地访问数据。根据您的架构,内存缓存可以使数据访问速度极快。
这是非常具体的案例,但如果 CP
不是唯一的(阅读:许多记录通常是相同的)你也可以使用 GROUP
查询
SELECT CP,COUNT(*) FROM CP GROUP BY CP
通过这种方式,您可以获得 CP
个具有计数的值,应该减少数据量
请阅读 SQL Injection 以使您的代码更安全
不是一个一个地获取 CP,而是执行单个查询,选择整个 table,然后在 table 中迭代。会大大提高速度。
您的查询将是:
"SELECT * FROM CP";
然后做类似的事情:
List<string> cps = table_name.AsEnumerable()
.Select(r=> r.Field<string>("...."))
.ToList();
一个经常使用 Access DB 的人的建议 - 始终使用参数化查询。它将为您避免大部分不兼容的类型错误。特别是当你处理日期时...
您可以尝试将整个 CP
table 缓存在字典中:
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。
修改:
var strId=string.empty;
lista.Foreach(x=>
{
strId+=","+x.itemKey;
});
var cp = consulta.returnCP(strId=strId.TrimStart(','));
所以这会将所有 id 作为逗号分隔传递给函数,它只会执行一次 SQL 查询,因此数据库连接只会打开一次。其余的逻辑应该插入存储过程中,因为 SP 再次比普通 SQL 查询快得多。将节省 90% 的时间。希望这有效。
我在 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();
}
}
这里的问题是所有对数据库的请求都需要花费大量时间才能完成。我看到循环运行良好,但肯定没有优化。
那么,我怎样才能提高该过程的速度?
一次获取更多数据 - 因为您提前知道 ID 列表,而不是通过调用一个一个地查询项目。如果您想要带有键
而不是执行 4 个查询(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,一次加载所有 ID 的效率会很低——最好将数据请求分成几个小块。这样他们仍然可以加载几百条记录,但不会太多。
如果数据访问仍然是一个瓶颈,并且您经常为相同的对象调用它,请考虑使用 缓存 - 它可以让您更快地访问数据。根据您的架构,内存缓存可以使数据访问速度极快。
这是非常具体的案例,但如果
CP
不是唯一的(阅读:许多记录通常是相同的)你也可以使用GROUP
查询SELECT CP,COUNT(*) FROM CP GROUP BY CP
通过这种方式,您可以获得
CP
个具有计数的值,应该减少数据量请阅读 SQL Injection 以使您的代码更安全
不是一个一个地获取 CP,而是执行单个查询,选择整个 table,然后在 table 中迭代。会大大提高速度。 您的查询将是:
"SELECT * FROM CP";
然后做类似的事情:
List<string> cps = table_name.AsEnumerable()
.Select(r=> r.Field<string>("...."))
.ToList();
一个经常使用 Access DB 的人的建议 - 始终使用参数化查询。它将为您避免大部分不兼容的类型错误。特别是当你处理日期时...
您可以尝试将整个 CP
table 缓存在字典中:
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。
修改:
var strId=string.empty;
lista.Foreach(x=>
{
strId+=","+x.itemKey;
});
var cp = consulta.returnCP(strId=strId.TrimStart(','));
所以这会将所有 id 作为逗号分隔传递给函数,它只会执行一次 SQL 查询,因此数据库连接只会打开一次。其余的逻辑应该插入存储过程中,因为 SP 再次比普通 SQL 查询快得多。将节省 90% 的时间。希望这有效。