1

こんにちは、私は C# と oracle 11g データベースで Visual Studio を使用しています。

特定の日付列で並べ替えられたデータグリッド内のすべてのデータを表示するボタンを備えたアプリケーションがあります。問題は、これに 20 秒から 30 秒かかりすぎることです。SQLでTOPを使用して検索を制限することを考えましたが、それは理想的な解決策ではないので、皆さんが助けてくれるかどうか疑問に思っていました.

私の問題はこの方法にあります:

public List<Adress> ListOprema()
    {
        string connectionString = "provider=ORAOLEDB.ORACLE; data source=ORCL; password=****; user id=****;";
        oleCon = new OleDbConnection(connectionString);
        List<Adress> _adressStore = new List<Adress>();


        try
        {
            oleComd = new OleDbCommand();
            oleComd.Connection = oleCon;
            oleComd.CommandText = "Select Oprema.Opr_Id, Oprema.Naziv, Oprema.Datum_Nabavke, Oprema.Datum_Zaduzenja, Oprema.Dobavljac, Oprema.Jedinica_Mjere,"+
            " Oprema.Zaduzio, Oprema.Vrijednost, Oprema.Kolicina_Nabavna, Oprema.Kolicina_Otpisana, Oprema.Kolicina_Trenutna, Oprema.Status, Oprema.Konto, "+
            " Oprema.KontoIsp, Oprema.Broj_Naloga, Oprema.Sifra_Objekta, Oprema.Sifra_Prostora, Dobavljaci.Naziv AS DobNaz, Radnik.Rad_Prez, Objekti.Objekat_ID"+
            " from OPREMA Oprema, DOBAVLJACI Dobavljaci, RADNIK Radnik, OBJEKTI Objekti"+
            " WHERE Oprema.Dobavljac=Dobavljaci.Dob_Id(+) AND Oprema.Zaduzio=Radnik.Rad_Id(+) AND Oprema.Sifra_Objekta=Objekti.Objekat_ID(+)"+
            " ORDER BY Oprema.Datum_Nabavke DESC";
            oleCon.Open();
            OleDbDataReader Reader = oleComd.ExecuteReader();

           while (Reader.Read())
            {


                int ix = Reader.GetOrdinal("DATUM_NABAVKE");
                int iy = Reader.GetOrdinal("DATUM_ZADUZENJA");
                int sifra =Reader.GetOrdinal("SIFRA_OBJEKTA");
                int sifraP = Reader.GetOrdinal("SIFRA_PROSTORA");
                int zaduzio = Reader.GetOrdinal("ZADUZIO");
                int prezime = Reader.GetOrdinal("RAD_PREZ");
                _adressStore.Add(new Adress()
                //_adressStore.Add(Adress.GetFromDataReader(Reader));
                {




                    Naziv = Reader["NAZIV"].ToString(),


                    //DatumNabavke = Convert.ToDateTime(Reader["DATUM_NABAVKE"]),

                    DatumNabavke = Reader.IsDBNull(ix) ? DateTime.Now : Reader.GetDateTime(ix),

                    DatumZaduzenja = Reader.IsDBNull(iy) ? DateTime.Now : Reader.GetDateTime(iy),

                    //DatumZaduzenja = Convert.ToDateTime(Reader["DATUM_ZADUZENJA"]),

                    InventurniBroj = Convert.ToInt32(Reader["OPR_ID"]),

                    Dobavljac = Convert.ToInt32(Reader["Dobavljac"]),

                    JedinicaMjere = Reader["Jedinica_Mjere"].ToString(),

                    Zaduzio = Reader.IsDBNull(zaduzio) ? null : (int?)Reader.GetDecimal(zaduzio),

                    Vrijednost = Convert.ToDecimal(Reader["VRIJEDNOST"]),

                    KolicinaNabavna = Convert.ToInt32(Reader["KOLICINA_NABAVNA"]),

                    KolicinaOtpisana = Convert.ToInt32(Reader["KOLICINA_OTPISANA"]),

                    KolicinaTrenutna = Convert.ToInt32(Reader["KOLICINA_TRENUTNA"]),

                    Status = Reader["Status"].ToString(),

                    Konto = Convert.ToInt32(Reader["Konto"]),

                    KontoIsp = Convert.ToInt32(Reader["KontoIsp"]),

                    BrojNaloga = Reader ["Broj_Naloga"].ToString(),

                    SifraObjekta = Reader.IsDBNull(sifra) ? null : (int?)Reader.GetDecimal(sifra),

                    SifraProstora = Reader.IsDBNull(sifraP) ? null : (int?)Reader.GetDecimal(sifraP),

                    ImeZaduzioca = (string)((Reader["RAD_PREZ"] == DBNull.Value) ? null : Reader["RAD_PREZ"]),

                    ImeDobavljaca = Reader["DobNaz"].ToString(),

                    IsNew = false,

                    IsReadOnly = true
                });



            }

            oleCon.Close();
            //} 
            //oleCon.Close();
        }
        catch (Exception ex)
        {
            oleCon.Close();
            MessageBox.Show(ex.Message);
        }

        return _adressStore;
    }

プロファイラーを実行し、これらの 2 つの行が最も高価であると報告しました

ホット パス名 包括的 % 排他的 % Inventar.UserControls.SearchBar.SearchText_Changed(object,class System.Windows.Controls.TextChangedEventArgs) 9,32 0,00 SAPBusinessObjects.WPF.Viewer.DelegateMarshaler.<>c_ DisplayClass2.b _0 (オブジェクト) 3,37 0,00

しかし、それは SearchText_Changed が条件を除いて同じ関数を呼び出し、条件がない場合に上記の関数を呼び出すためです (つまり、検索フィールドが空の場合)。

また、Oracle の jdeveloper で autotrace を実行しました (クエリは非常に高速に実行されますが、それはおそらく重要なことではありません)。結果は次のとおりです。

SELECT STATEMENT 
         22        

 SORT ORDER BY 
         22      972 

 NESTED LOOPS OUTER 
         20      972 

 HASH JOIN RIGHT OUTER 
         20      61 

 Access Predicates 

 OPREMA.ZADUZIO=RADNIK.RAD_ID 

 TABLE ACCESS FULL 
 RADNIK      5       16 

 HASH JOIN RIGHT OUTER 
         15      45 

 Access Predicates 

 OPREMA.DOBAVLJAC=DOBAVLJACI.DOB_ID 

 TABLE ACCESS FULL 
 DOBAVLJACI      3       7 

 TABLE ACCESS FULL 
 OPREMA      11      38 

 INDEX UNIQUE SCAN 
 OBJEKTI_PK      0       911 

 Access Predicates 

 OPREMA.SIFRA_OBJEKTA=OBJEKTI.OBJEKAT_ID 

友人は、アプリケーションの読み込み時にすべての監視可能なコレクションを埋めてから、代わりにコレクションを検索することを提案しましたが、どこから始めればよいかわかりません。まだ初心者です。

とにかく、皆さんが助けてくれることを願っています。

4

1 に答える 1

0

問題はSQLにあるのではなく、タブ付きビューとDataGridにあることがわかりました。彼らは一緒にうまくプレーしていないようです。ListViewに切り替えると、60%高速になりました。新しいウィンドウを開くと、1秒以内に完了します。皆さんの助けに感謝します。

于 2012-11-23T14:31:24.383 に答える