Multiple DataReaders or one DataSet faster?

E

Earl

I have 7 combos I want to populate at once. Which provides the best
performance: multiple DataReader fills for each combo or one call to SQL
server to fill a DataSet and then bind with DataViews? Note that the DataSet
method would require multiple joined tables in the stored procedure.
 
C

Cor Ligthert

Hi Earl,
I have 7 combos I want to populate at once. Which provides the best
performance: multiple DataReader fills for each combo or one call to SQL
server to fill a DataSet and then bind with DataViews? Note that the DataSet
method would require multiple joined tables in the stored procedure.

This I do not understand, the select for the reader will normaly not be
different from the select for your dataset.

I think that the performance will not be that different that anybody will
notice that and asume that the dataset will be faster, it is not magic, just
an class to do effective datacollection using the datareader.

Cor
 
W

William Ryan eMVP

Hi Earl:
Earl comcast net> said:
I have 7 combos I want to populate at once. Which provides the best
performance: multiple DataReader fills for each combo or one call to SQL
server to fill a DataSet and then bind with DataViews?
If you can grab the data once, vs. grabbing it 7 times, even if you grab it
7 times with a Reader and once with a Dataset, grabbing it once will be
faster
Note that the DataSet
method would require multiple joined tables in the stored procedure.

Not true. You can use DataRelation for instance, And since you are using
SQL SErver, you can use batch queries so you can do both. Doing Joins on
the server is not advised, I'd really consider using the DataRelation
instead b/c you aren't pulling redundant data over the network and wasting
other resources.

YOu can stack your queries in a proc or just append them in your command
text. You use while(dr.Read()){

}
from the reader to advance WITHIN the current set, but if you had a proc or
sql statement with say 7 different Select statments, you'd use
DataReader.NextResult to get to the next resultset. SO it'd be an outer
loop of nextresult with an inner loop of .Read.

You aren't in an either or scenario though. You can still use a Joined table
w/ the data reader although I'd try to avoid those.
If you can just pull the data over once, use a relatino or two, and bind
different combos to the same data, I think your overall performance will be
much better.

http://www.knowdotnet.com/articles/datarelation.html
 
E

Earl

Ahhhh, good stuff here William. Perhaps I misspoke when I said JOINS were
"required" .... I appreciate the advice on using the DataRelation instead.
 
W

William Ryan eMVP

Hi Earl:

Sorry if I glommed onto the word. I know a lot of words can have multiple
meanings, join being a great example.I've seen some people do some really
complex joins on tables before and try to use a CommandBuilder to gen the
update logic which, shall we say, didn't work. Anyway, I've definitely made
my share of mistakes with stuff, and using Joins to pull back a ton of data
when I was first learning ADO.NET was a frequent one. Those DataRelations
saved my butt and made life a lot more pleasant ;-).

Let me know how it works and if you have any problems, i'll do what I can.
 
E

Earl

I read a couple of your articles and one item caught my attention. If I
interpret correctly, you mentioned that since a DataSet is an approximation
of your database, then only one DataSet per application is needed. A couple
of questions come to mind: Where would you instantiate the DataSet? Doing
so, I envision that you would add DataAdapters, etc. as needed throughout
instead of at the moment you make the initial fill. Please elaborate on your
comment. Thanks.
 
C

Cor Ligthert

Hi Earl,

I answered before that the dataadapter holds a sophisiticated datareader.

You can (normaly) use
datasets with a lot of tables..
datasets with a single table
datatables

When you use datasets with a lot of tables you can set a relation inside
your program or use the relations as made in your database.

However I do not see that as your problem, you only want to fill combo's.

The dataset or datatable can binded with one property (the datasource) to
the combo, that is a big advantages above using the datareader which cannot
be used as datasource for the combobox.

I hope this helps?

Cor
 
E

Earl

Actually what was gained by the dataset over the datareader was the ability
to use dataviews to "disconnect" fields in the same table to fill separate
lists (which also populates another object). The "problem" wasn't per se how
to use the datareader or the dataset for this particular task, but whether
one or the other would be the best from a performance standpoint. I've done
some rough estimates and really am not sure if performance was increased or
decreased, but the dataset gives much more flexibility, so thus worth the
overhead cost of using it (note that since the datareader emulates a
forward-only ADO recordset it is less network and processor-intensive).
William's recommendation was to avoid JOINs on the server, and to use the
dataset/data relations instead. For the simple task of loading unrelated
lists, I had no reason to use the data relations but would certainly need it
on subsequent classes (which deal with pricing based on a custom
configuration). Nonetheless, William got me to thinking more along the lines
of using just *one* dataset for the entire app and thus my question to him
remains.
 
W

William Ryan eMVP

<<I read a couple of your articles and one item caught my attention. If I
interpret correctly, you mentioned that since a DataSet is an approximation
of your database, then only one DataSet per application is needed. >> As a
general rule, Yes, this is correct. I see wayyyy too much code with
multiple datasets and no apparent reason for this. I think a lot of code
examples use datasets and datatables interchangeably and many examples use
datasets even if there is only one table in the dataset, so many get the
impression that they are interchangeable. While they are in many regards
(you can bind a Grid for example to a datatable or a dataset and if you bind
it to a one table dataset, the result is indistinguishable between the two),
remember that they are different objects. A DataSet is essentially a
collection of DataTables. If you create a DataSEt with one table, remember
that you've created Two objects, not one. If all the functionality you need
can be handled with just one, it's inefficient to do this (However, if you
need the functionality or have a good reason, then don't worry about it.
Just make sure the benefit is worth the cost).

Anyway, there are instances when you may need more than one dataset or it
logically makes sense to have more than one... after all, there are many
times when you have more than one named instance of a server that you use in
a project b/c your company splits its data for whatever reason (your HR
Application runs on Oracle, your CRM runs on SQL Server, etc).

<<Where would you instantiate the DataSet? >> It really depends on the
app... some of my apps only have one or two forms, others have hundreds.
You basically have two choices.

The first and easiest is to create a class that's sealed, with all static
members and is a single instance class. You can implement a singleton
pattern or you can just have a class with all static properties and methods.
One of the properties will be A dataset. You could just use this one
property to reference your tables or you could create another property for a
table or tables and then in your get accessor, do something like this inside
the class

public static DataTable Customers{

get{return this.ProjectDataSet.Tables["Customers'];}
}

outside the class you'd get at it like, foreach(DataRow dro in
mySharedClass.Customers.Rows){

}

Or, you could not use a property for the tables(s) and just do this

foreach(DataRow dro in mySharedClass.ProjectDataSet.Tables["Customers"]){

}

They are the same thing, it's just one way lets you access the tables
directly and is ostensibly more 'object oriented' YOu could also use this
class to return aggregetes with DataTable.Compute, or filtering with
DataView.Rowfilter ---- I've written on this extensively at
www.knowdotnet.com under William Ryan or DataAccess (Efficiently Using
ADO.NET 1,2 & 3 and any of my DataView articles)

You can also declare it wherever and just pass it around or use it to set
the properties of your business objects, then have the business objects do
their thing and when they return, modify the dataset accordingly. The
architecture plays a big role here but this is definitely one viable way.
SO maybe you call a web service or your DataAccess layer and fill the
dataset at the beginning. It's instantiated in your Main form. THen you use
it to populate some business objects, pass the business objects around and
when all is said and done, take them and fill/add/delte/change stuff in your
dataset. Rocky Lhotka has a book on Business Objects in VB.NET or C# (I
forget the name) where he uses an approach something like this (although I'm
not doing it justice b/c it's much more clever than the briefl little piece
I described>

As far as DataAdapters, doesn't really matter. Remember that you give them
a Select, Update, Delete and INsert command, and they do the rest. All
they ne3ed is a datatable, then they look at the Rowstate and make a
determination, one row at a time, which command to call against each row
based on its state. So you can fill a dataset with a dataadapter in Form1,
then have a another dataadapter in some dataaccess.dll that has the same
commands, change the values in your datatables, and call update with the
adapter from the .dll and provided they had the same update/insert/etc
commands, the behavior would be identical. Adapaters don't care where the
data came from...as long as they have their commands and those commands
match the table they are updating, all is well. But you'd probably want to
keep your adapters in a similar place, in a dataaccess class that you can
get to from anywhere (but, since they don't need to preserve their state
like DataSet/datatables do, it doesn't matter if you instantiate a new
instance (from a dataaccess point of view...from an efficiency point of
view, you don't want to just create new adapters willy nilly - or any other
object for that matter). Remember the #1 thing... DataSets/dataTables have
to know the Rowstate of their rows to be of much use in update scenarios.
So preserving state is crucial. As such, one instance, (shared in VB.NET,
static in C#) visible from everywhere is what you are after in this case.
DataAdapters don't need state or care about thier own, only about the state
of the rows of the table they are asked to update. (provided they have valid
commands).


Does that help? IF not, let me know and I'll elaborate more...
 
E

Earl

Excellent dissertation on the ins and outs of the dataset Bill! I'm still
digesting the second half of that, but I do have one followup question:

You say "one instance, (shared in VB.NET, > static in C#) visible from
everywhere is what you are after in this case." I'm currently using a Public
Shared instance in my startup MDI form/class -- but not with static
variables. This does work but I'm certainly curious if there is a better way
or a downside. Thanks again for a great "article"!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top