2011-07-08 64 views
3

我有以下代碼查詢數據庫並填充數據表。有沒有更快的方式來填充數據庫查詢的結果集?

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行。這裏是什麼在這裏面調用.NET事情的輪廓細節:

enter image description here

考慮到我的運行查詢,將其轉換成一個數據表,然後將該錶轉換爲對象的列表,是還有什麼我可以做的優化這個(以某種方式直接從數據適配器轉換爲對象列表?)。我基本上正在尋找解決此代碼中的性能瓶頸的解決方法?

+0

如何的有10秒鐘的時間僅僅是接收數據的時間?不加載數據表,只是*獲取*它。問題可能不是代碼,它可能是數據庫,網絡等。 –

回答

2

我認爲確保您的查詢快速運行是答案。代碼不能快得多,但優化查詢可以產生巨大的差異。你可以使用SQL分析器並檢查原始SQL查詢的執行嗎?

例如添加數據庫索引或返回更少的列。網絡延遲也會導致緩慢。數據庫是否與代碼執行在同一個LAN上?

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; 
    } 

,因爲正通過數據庫結果第一次去輪,沒有第二或第三平移階段需要創建特定於域的對象這應該表現良好。

+0

謝謝..我轉換爲使用上面的代碼。雖然它有道理,爲什麼它會比我上面做的更有效率,在分析後(使用dottrace),總體時間幾乎相同 – leora

0

如果你正在尋找速度不使用數據集/數據適配器,他們是一個不爲速度而構建的舊技術。 使用像Sean建議的數據讀取器。

0

除了DataReader,你可以檢查你的查詢是否設計得很好。

也許你可以優化它或事件將其分割成多個並行的行動

相關問題