2017-09-25 32 views
0

問題のドメインは、〜90000行と6列のようなdbファイルがあることです。私はすべての行と列を私のために必要な取得し、それはうまく動作するSelectクエリを得ました。今私はそれらのレコードでDataTableを埋めることです。私はSQliteDataAdapterのFillメソッドでこれを行います。これには約1.3秒かかります。その後、ObservableCollection(< - DataGridにバインドされています)にこのデータを入力します。これには約1,3秒もかかります。だからここに私のコードはC#SQLiteDataAdapter Fillメソッドが遅い

private void GetSelectedMaterial() 
    { 
     DataTable dtMaterial = new DataTable(); 
     materialColl.Clear(); // Clearing ObservableCollection 

     Trace.WriteLine("GetSelectedMaterial TS " + DateTime.Now + DateTime.Now.Millisecond); 
     using (SQLiteConnection connection = new SQLiteConnection(dbConnection)) 
     using (SQLiteCommand cmd = connection.CreateCommand()) 
     { 
      connection.Open(); 

      query = "SELECT * FROM Tbl_Materialliste LEFT JOIN(SELECT * FROM Tbl_Besitzt k WHERE k.TechnikID = '" + teTechnikID + "') as k ON k.MaterialID = Tbl_Materialliste.MaterialID"; 

      dataAdapter = new SQLiteDataAdapter(query, connection); 
      Trace.WriteLine("query: " + DateTime.Now + DateTime.Now.Millisecond); 

      dtMaterial.Columns.Add("Checked", typeof(bool)); 
      Trace.WriteLine("here comes the fill: " + DateTime.Now + DateTime.Now.Millisecond); 
      dataAdapter.Fill(dtMaterial); 

      Trace.WriteLine("Checkbox: " + DateTime.Now + DateTime.Now.Millisecond); 
      DetermineCheckBox(dtMaterial, teTechnikID, 8); 
      Trace.WriteLine("SQL TS: " + DateTime.Now + DateTime.Now.Millisecond); 
     } 

     FillMaterialColl(dtMaterial); 
    } 

    private void FillMaterialColl(DataTable dtMaterial) 
    { 
     foreach (DataRow dr in dtMaterial.Rows) 
     { 
      Material mat = new Material(); 

      mat.isChecked = (bool)dr.ItemArray[0]; 
      mat.materialID = (string)dr.ItemArray[1]; 
      mat.materialkurztext = (string)dr.ItemArray[2]; 
      mat.herstellername = (string)dr.ItemArray[3]; 
      mat.herArtikenummer = (string)dr.ItemArray[4]; 
      mat.dokument = (string)dr.ItemArray[5]; 
      mat.substMaterial = (string)dr.ItemArray[6]; 

      materialColl.Add(mat); 
     } 
    } 

である私はObservableCollectionsがパフォーマンスを排出している知っているが、別の方法でこれを行うにはいくつかの方法がありますか?一部の人はDataAdapterの代わりにDataReaderを使用すると言いますが、DataAdapterはDataReaderを使用するため、パフォーマンスの向上はないと思います。 enter image description here

:だから、主な問題は、そのプロセスが長いにかかり、新しい材料を示すことは約3~4秒かかる場合、ユーザーエクスペリエンスがあまり良くないということです。..

EDIT だからここに私のDB設計が来ます

それはTbl_MaterialとTbl_Technikの多対多の関係です。 私の選択クエリは、Tbl_Material(〜90k)のすべてのエントリと、Tbl_Besitztからのこれらのカラムを提供します。technikID を見つけることができます。チェックボックス)、私のMaterialIDに属する項目 Tbl_Materiallisからの私のDBファイルMaterialId teはPKでTbl_TechnikのTechnikIDです - あなたがデザインイメージに疑問を持っているわけではありません。私はそれらをモデルに入れませんでした。

ありがとう!

+0

はい、そうですが、バックグラウンドスレッドなしでこれを行うと変更されません...スレッドを必要としないようにコードを編集します。 – user8574993

答えて

0

スキーマと設計が分からずにデータベースのパフォーマンスの問題を調査するのは難しいです。 SQLクエリには、joinの式があります。結合操作を高速化するために、対応するデータフィールドが索引付けされていることを確認する必要があります。これは、データサイズがの場合にも、両方ともテーブルに依存します。

検索結果の表示を高速化するには、ObservableCollection<T>に項目を追加しないでください。これは、新しいアイテムを追加するたびに、バインディング・エンジンがこのアイテムをDataGridに転送するため、グリッドがレコードを表示するのに必要なすべてのアクションを実行するためです。あなたの方法では

public IEnumerable<Material> Materials 
{ 
    get { return this.materials; } 
    private set 
    { 
     // Using the PRISM-like implementation of INotifyPropertyChanged here 
     // Change this to yours 
     this.SetProperty(ref this.materials, value); 
    } 
} 

あなたが本当にそしてちょうどIEnumerable<T>にそれを作る、(例えばあなたがビュー内の任意の項目を追加したり、削除されません)に観察するコレクションを必要としない場合、ローカルList<Material>を作成し、それを埋める、その後、ビューに公開:

List<Material> materials = new List<Material>(); 
// fill the list here 
// ... 
// finally, assign the result to your property causing the binding to do the job once 
this.Materials = materials; 

あなたががObservableCollection<T>が必要な場合は、同じトリックを行うことができます - ローカルコピーを作成し、それを埋める、そして最終的に公開します。

これでも問題が解決しない場合は、UI仮想化を試してみてください。これはむしろ大きな話題ですが、ネット上には多くの情報があります。

+0

私はそれを記述したように変更しましたが、現在はリストを埋めるのに250msくらいです!どうもありがとう!私は私のdbデザインを見ることができるように私の投稿を編集するので、多分あなたは一見をすることができますか? – user8574993

関連する問題