3

My Windows form Application contains OleDbDataAdapter, it is consuming longer time to fetch data from remote DB. It is not able to retrieve/Hold table data like 5000 rows(Application gets struck). Here is my code.

environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
string strConnString = environments[envs];
conn = new OleDbConnection(strConnString);
conn.Open();
OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
DataSet ds1 = new DataSet();
objDa.Fill(ds1);
dataGridView1.DataSource = ds1.Tables[0];

Environment section is configured in app.config file :

<configuration>
  <configSections>
    <section name ="Environment" type="System.Configuration.NameValueSectionHandler" />
  </configSections>

  <Environment>
    <add key ="CIT" value ="Password=pwd123;User ID=abc123;Data Source=db1;Persist Security Info=True;Provider=MSDAORA"/>
    <add key ="SIT" value ="Password=pwd234;User ID=abc234;Data Source=db2;Persist Security Info=True;Provider=MSDAORA"/>
    <add key ="UAT" value ="Password=pwd345;User ID=abc345;Data Source=db3;Persist Security Info=True;Provider=MSDAORA"/>

  </Environment>
</configuration>

It would be greatful if someone could suggest better approach/mechanism with code.

Shalem
  • 1,446
  • 2
  • 22
  • 47
  • what happens exactly? are you sure that your connection to the database is working? does it work if you do a "select top 10 * from .." ? – Vland Sep 15 '14 at 07:20
  • I've got connected and able to execute commands on DB. 1. Every time i execute an command, i see my application makes connection freshly to DB. 2. My Application consumes more time when its retrieving more records as result(lets say more than a 1000 records). Need to minimise this time – Shalem Sep 15 '14 at 07:25
  • 1
    Even I was happy with the disconnected architecture, and the lot of data related supported objects. But all happiness lost after a few "real time" implementations. From my experience, I myself created certain rules while working with ADO.NET. 1. Never load everything into a dataset (NO select * from table). Select ONLY the columns that you need. 2. If you know that there is going to be more than few thousands of rows in the table, load it in a paged manner. 4. Always use stored procedures, than inline queries. 5. Use SSMS, execution plan, and optimize the query inside the SP. – Thangadurai Sep 15 '14 at 07:27
  • " Every time i execute an command, i see my application makes connection freshly to DB." - you should be closing your connection each time you use it - preferably with the "using" statement. – Joe Sep 15 '14 at 07:28
  • Since it is a windows application, you can create a separate thread to load the data in the background, and you can provide some nice feedback to the user, thread also helps to keep the UI active – Thangadurai Sep 15 '14 at 07:29
  • how "remote" is your db? – Vland Sep 15 '14 at 17:19
  • I dint get you....plz let me know what you meant exactly - Vland – Shalem Sep 16 '14 at 09:11
  • OleDbDataReader retrieved data in lesser time better compared to OledbDataAdapter. Thanks for suggestion. Still need to minimize time to retirieve data from Db especially in case of more volume of data(1000's of records). I believe paging would serve the purpose. Please suggest – Shalem Sep 17 '14 at 11:17
  • 2
    If you absolutely need all your data, you can initially fetch the first, 200 rows directly, and then fetch the rest silently in the background in a new thread. That should keep your user engaged and your UI interactive. Also, you can retrieve your data in chunks of 200 rows each time. – MrClan Sep 18 '14 at 11:35
  • Why the other answer vanished ? – Larry Sep 20 '14 at 12:58

2 Answers2

3

Did you try to work with threads. create a sub function somewhere in your program like below

public void dataPullingThread(){
    try{
        //your connection code goes here like below//
        environments = ConfigurationManager.GetSection("Environment") as NameValueCollection;
        string strConnString = environments[envs];
        conn = new OleDbConnection(strConnString);
        conn.Open();
        OleDbDataAdapter objDa = new OleDbDataAdapter("select * from tblABC", conn);
        DataSet ds1 = new DataSet();
        objDa.Fill(ds1);
        dataGridView1.DataSource = ds1.Tables[0];
        conn.Close();
    }
    catch (Exception e){

    }

}



//call your thread from desired location in program///

using System.Threading;
Thread thread = new Thread (new ThreadStart(dataPullingThread));
thread.start;

//Your application will continuously run; however, the data will appear when ever the thread auto kills itself. You can boost the speed if you create more then one thread. That means each thread selecting different rows of the database, I hope this information will help you//
Keshab
  • 142
  • 11
2

Here are some general ADO.NET optimization tricks:

  • Instead of doing SELECT *, please ensure that you really need all the fields. The problem is that many unused field values might be retrieved and it consume resources.

For example, do SELECT Field1, Field2, Field3 instead of SELECT * if your table contains more than those three fields.

  • Stick to the following connection open/close pattern:

Example:

using(var con = new OleDbConnection(strConnString))
{
    con.Open();

    ...

    con.Close();
}

So the connection is closed even if wrong things happens, and the connection pooling mechanism will be used on the server side.

  • The DbDataReader object is much faster. Please try to use a DbDataReader instead of a DbDataAdapter. Use it to fill a generic List, then bind your DataGrid to that List.

However, it looks like something is wrong with your connection itself. How can you be sure the application is fetching data or trying to establish a connection ? To check this, change your query to a very fast one like "select sysdate from dual" to check whether the problem is coming from a connection attempt or not.

Larry
  • 17,605
  • 9
  • 77
  • 106
  • Im pretty sure on application gets connected to DB. I'Ve debugged and examined connection status and ran few commands including "Select sysdate from dual". Let me try with DbDataReader - Hope Works – Shalem Sep 15 '14 at 08:15
  • I see your connecting to an Oracle database. You might want to see if you can return smaller subsets of data e.g 5 x 1000 records at a time to see if that helps. You might also want to review the indexing on the table that your getting data from to ensure your SELECT WHERE statement is using the index (if the table is very large). – Jamie Clayton Sep 16 '14 at 01:40
  • How can we return small subsets of data to display on dataGridView? Did u meant paging concept? If not paging, could you provide some code to return smaller subsets of data - Would be much helpful – Shalem Sep 16 '14 at 09:16
  • Your suggestion for DbDataReader worked some extent. Thanks @Larry – Shalem Sep 17 '14 at 11:19
  • 1
    ODP.Net has some options to bulk fetch the data, also you can set the Fetch Size, which will ensure that you can get data in chunks behind the scene. It helps in optimizing the Read operation – Mrinal Kamboj Sep 18 '14 at 08:39
  • The free dotConnect Express edition for Oracle (DevArt) works great. You may want to give it a try: http://www.devart.com/dotconnect/oracle/download.html – Larry Sep 18 '14 at 08:42