代码是这样的:
public class Email
{
public string MailAddress {get;set;}
public string MailOwner {get;set;}
public int MailSended {get;set;}
public int MailReceived {get;set;}
}
public class EmailList
{
public List<Email> Items {get; private set;}
private IDBConnection _connection;
public EmailList(IDBConnection connection)
{
_connection = connection;
}
public List<Email> GetEmails(int customerId)
{
var emailList = new List<Email>();
var sql = "SELECT * FROM EmailsAddress WHERE Id = '" + customerId + "'";
using (var ObjectToAccessDatabaseAndStoreResultsIntoDataTable = new ObjectToObtainDbResultsIntoDataTable(_connection, sql))
{
foreach(DataRow row in ObjectToAccessDatabaseAndStoreResultsIntoDataTable.Datatable)
{
var email = new Email{
MailAddress = Convert.ToString(row["MailAddress"]);
MailOwner = Convert.ToString(row["MailOwner"]);
MailSended = Convert.ToInt32(row["MailSended"]);
MailReceived = Convert.ToInt32(row["MailReceived"]);
}
emailList.Add(email);
}
return emailList;
}
}
当多次调用GetEmails()
来检索邮件地址时,对于2000个客户,返回时需要很长时间。使用SQL Server Profiler,我发现大部分时间都是GetEmails()
例程。
为什么GetEmails()
例程需要这么长时间?我正在使用SQL Server。
答案 0 :(得分:2)
您的EmailsAddress表中的Id列是否在此列上有索引?如果没有,添加一个将加快速度。
您总是应该使用参数化查询而不是字符串连接 - 它允许数据库优化您的查询,更重要的是,它可以保护您免受SQL注入攻击(尽管在您的情况下与整数类型不相关)
var command =
new SqlCommand("SELECT * FROM EmailsAddress WHERE Id = @Id;", db);
command.Parameters.AddWithValue("@Id", yourTextValue);
command.ExecuteQuery();
Patrick Hofman所说的是,在查询客户时,通过对ID进行分组或使用联接来为您的客户提供服务将会更有效率。
/编辑:这是一个询问多个ID的查询示例:
var command =
new SqlCommand("SELECT * FROM EmailsAddress WHERE Id IN (@Id1,@Id2,@Id3);", db);
command.Parameters.AddWithValue("@Id1", 1);
command.Parameters.AddWithValue("@Id2", 54);
command.Parameters.AddWithValue("@Id2", 96);
command.ExecuteReader();
或者,忽略我自己的使用参数的建议:
var sql = "SELECT * FROM EmailsAddress WHERE Id IN (1,54,96)";
在循环中执行此操作的示例,参数:
var ids = new int[] { 1, 95, 46, 93, 98, 77 };
var isFirst = true;
var commandBuilder = new StringBuilder("SELECT * FROM EmailsAddress WHERE Id IN (");
var command = new SqlCommand("");
for (var i = 0;i<ids.Length;i++)
{
if (!isFirst) commandBuilder.Append(",");
else isFirst = false;
var paramName = "@Id" + i;
commandBuilder.Append(paramName);
command.Parameters.AddWithValue(paramName, ids[i]);
}
commandBuilder.Append(")");
command.CommandText = commandBuilder.ToString();
command.ExecuteReader();
// Read your result
答案 1 :(得分:1)
你能找到问题所在吗?
是的,您正在向数据库发送2000个SQL语句,该数据库必须逐个解析并执行它们,而在这种情况下,一个SQL语句就足够了。
您可以做什么,具体取决于数据库的大小:
GetEmails
方法的紧密循环。您可以传入客户ID列表并立即获取。这需要in
上的customerId
声明。答案 2 :(得分:1)
您可以获取此类列表客户的电子邮件地址
public List<Email> GetEmails(List<int> listCustomerId)
{
var emailList = new List<Email>();
var sql = "SELECT * FROM EmailsAddress WHERE Id IN (" + string.Join(",", listCustomerId) + ")";
using ( var ObjectToAccessDatabaseAndStoreResultsIntoDataTable = new ObjectToObtainDbResultsIntoDataTable(_connection, sql))
{
foreach (DataRow row in ObjectToAccessDatabaseAndStoreResultsIntoDataTable.Datatable)
{
var email = new Email
{
MailAddress = Convert.ToString(row["MailAddress"]);
MailOwner = Convert.ToString(row["MailOwner"]);
MailSended = Convert.ToInt32(row["MailSended"]);
MailReceived = Convert.ToInt32(row["MailReceived"]);
}
emailList.Add(email);
}
return emailList;
}
}