我有以下代码查询数据库并填充数据表。
private DataTable Run(string sql)
{
var conn = new OdbcConnection();
string connString = "[myConnString];";
conn.ConnectionString = connString;
conn.Open();
var da = new OdbcDataAdapter {SelectCommand = conn.CreateCommand()};
da.SelectCommand.CommandText = sql;
var dt = new DataTable();
da.Fill(dt);
da.Dispose();
conn.Close();
return dt;
}
我刚刚在它上面运行了一个分析器,它表明这行需要很长时间:
da.Fill(dt);
查询仅返回大约1000行。以下是此次电话会议内部网络内容的详情:
鉴于我正在运行查询,将其转换为数据表,然后将该表转换为对象列表,我可以做以下任何事情来优化它(以某种方式直接从数据适配器转换为对象列表??)。我基本上是在寻找这个代码中这个性能瓶颈的解决方法吗?
答案 0 :(得分:2)
我认为确保您的查询快速运行就是答案。代码不能快得多,但优化查询可以产生巨大的差异。您可以使用SQL事件探查器并检查原始SQL查询的执行吗?
例如,添加数据库索引或返回更少的列。网络延迟也可能导致缓慢。数据库与代码在同一个LAN上是否正在执行?
答案 1 :(得分:1)
我建议使用OdbcDataReader和Transform函数。以下内容应该有效:
public class OdbcQuery
{
OdbcCommand Command { get; set; }
public OdbcQuery(OdbcConnection connection, string cmdText)
{
Command = new OdbcCommand(cmdText, connection);
}
public List<T> Transform<T>(Func<OdbcDataReader, T> transformFunction)
{
Command.Connection.Open();
OdbcDataReader reader = Command.ExecuteReader(CommandBehavior.Default);
List<T> tList = new List<T>();
while (reader.Read())
{
tList.Add(transformFunction(reader));
}
Command.Connection.Close();
return tList;
}
}
这是一个示例转换函数,它将为查询中的每一行创建一个T类型的实例。在这种情况下,它只是一个Foo对象,
public class Foo
{
public Foo() { }
public string FooString { get; set; }
public int FooInt { get; set; }
}
class Program
{
public static List<Foo> GetFooList(string connectionString, string cmdText)
{
OdbcQuery query = new OdbcQuery(new OdbcConnection(connectionString), cmdText);
List<Foo> fooList = query.Transform(
rdr =>
{
Foo foo = new Foo();
foo.FooInt = rdr.GetInt32(0);
foo.FooString = rdr.GetString(1);
return foo;
});
return fooList;
}
这应该表现良好,因为您的特定于域的对象是在第一轮中通过数据库结果创建的,不需要第二或第三个翻译阶段。
答案 2 :(得分:0)
如果您正在寻找速度,请不要使用数据集/数据适配器,它们是一种不是为速度而构建的旧技术。 使用Sean建议的数据加载器。
答案 3 :(得分:0)
除了DataReader,您还可以检查您的查询是否设计得很好。
也许您可以对其进行优化或将事件拆分为多个并行操作