How to organize dataset queries to improve performance - asp.net

I don't know when to add to a dataset a tableadapter or a query from toolbox. Does it make any difference?
I also dont know where to create instances of the adapters.
Should I do it in the Page_Load?
Should I just do it when I'm going to use it?
Am I opening a new connection when I create a new instance?
This doesn't seem very important, but every time I create a query a little voice on my brain asks me these questions.

Should I just do it when I'm going to use it?
I would recommend that you only retrieve the data when you are going to use it. If you are not going to need it, there is no reason to waste resources by retrieving it in Page_Load. If you are going to need it multiple times throughout the page load, consider saving the query results to a private variable or collection so that the same data can be reused multiple times throughout the page load.
Am I opening a new connection when I create a new instance?
Asp.net handles connection pooling, and opens and closes connections in an efficient way. You shouldn't have to worry about this.
One other thing to consider from a performance perspective is to avoid using Datasets and TableAdapters. In many cases, they add extra overhead into data retrieval that does not exist when using Linq to Sql, Stored Procedures or DataReaders.

Related

Should I use Session/Cache to store the DataSet or should I fetch fresh from the Database each time?

The amount of coding that goes into the making of a DataSet is often significant. Now I'm not sure what the industry standard or best practise when dealing with data requests from multiple ASP.NET pages. Should I use a cache/session to pass on the DataSet from page to page or should I fetch directly from the database for each page?
What's the most common approach here?
Here are my thoughts:
It depends on the database and the type of data that you're trying to get, as well as what may modify the data. Do you have backend processes that run concurrent with the data you're going to want? Is this data only updated because of the current page, or does it update at all? How many people are going to use said page?
I personally almost always call to the database, simply because there are so many what-ifs when it comes to this kind of thing. At any time the data can change; it's never as static as people would think it would be. I would personally trade correct data over performance any day.
But that's just me personally. This question is so open ended that it's impossible to take every single thing into consideration since I don't know your database structure, nor how expensive it is to retrieve it, nor what you're using it for.
Sorry I couldn't really be more help.
It depends upon you need. If data size is very large then don't save it in Session or Cahce, because Session or Cache is stored in server Memory. Session is user specific and it will store data for each user in the server, so avoid from it. I think you should directly fetch data each time you need, don't save it in session. If data is very small/limited then you can save it in session ( example UserName or UserId etc ). If you are using a gridview to showdata then use paging and on each page request fetch the data from the database.

cache data until changed

I have a legacy website that needs a little optimization because of poor performance. It is an asp.net shopping website with linq to sql as data layer and MVP pattern as UI pattern.
The most costly entities in the db are product and category tables that have a one to many relationship. These two entities might not change regularly unless a user of admin group decides to add a product or category… etc. i was wondering how resource costly would it be to create and fetch everything from these two entities for each request! so if i could have had a way to keep my data alive…
first I thought well let’s use AJAX for data retrievals so I will create only those entities that I need to query or bind to, but wait, how can I do that without creating a new DataContext instance?!!
At the other side, using cache for whole DataContext is considered a bad decision because of memory cost. So what would be the best option here? How can I improve things?
UPDATE
1) doing what #HatSoft suggested.
Cons: those approaches will not help your code, only the database. beside this, there might be memory issues since we're putting data in memory instead of rendered html, however this might be the best option regarding de-coupling.
2) using output caching we have this code in an http handler with *.aspx wildcard:
string pagePath = Context.Request.Url.AbsolutePath;
object cacheKey = application[pagePath];
if(cacheKey == null)
return; //application restarted/first run so cache the stuff
else
Context.Response.RemoveOutputCacheItem(pagePath);
Cons: now we should link the pagePath to each database entity that the page uses, but if i do so then i'm coupling things instead of de-coupling them. this approach also will run into a little hard coding.
3) another solution would be output caching in post-cache mode instead of control cache mode. using Subsituation element and setting the OutPutCache Duration to 86400 so the page will be re-created every 24 hours.
Cons: hard coding user controls to produce the html output for Subsituation element dynamically.
so what do you suggest?
I would suggest you look in to SqlDependency class please read this article http://www.asp.net/web-forms/tutorials/data-access/caching-data/using-sql-cache-dependencies-cs
Also I would suggest you look in to loading data in the cache at application startup if it suits your application. Please see a good example here http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-at-application-startup-cs
With Linq2SQL you can use LinqToCache which offers a SqlDependency powered cache for your LINQ queries. It transforms the IQueryable<Products> into IEnumerable<Products> and enumerates form memmory after first access (first iteration of the underlying IQueryable). Based on SqlDependency data change notifications it invalidates the list and subsequent access will query again from DB, and cache the result.
My recommendation would be to cache the Products list and Categories in memory, since they change seldom and I expect them to be of a fairly constrained size.

ASP.NET: Create static collection for table data that doesn't change

I'm creating an ASP.NET MVC app that uses EF to perform all DB tasks.
There's a couple of related tables in the database that never change and I was thinking on creating a static collection that retrieves the data from those two tables (it's a few hundred records) the first time it is requested and just stores it in an object to prevent hitting the database every time.
Since I've read several people saying that you should avoid static objects in ASP.NET I was wondering if this was a bad practice or if it is acceptable for scenarios like this (read-only and small amount of data which should prevent concurrency problems).
Also I would like to know if there are other better alternatives to do this.
Thanks.
I have done exactly what you are planning on doing for exactly the same reason. It has been working well for several years already.
Just make sure that you get the initialization of the data right and you should be fine. When initializing, keep in mind:
Don't use locking if at all possible (or your app will deadlock 2
minutes before you're going on vacation)
You MUST NOT under any circumstance let a static constructor fail
Make sure no consumer of your cache has the ability to modify it
If the data isn't really static and you would actually need to re-read it fairly often then this might not be the best solution.
Just in case you're wondering, I've used this approach to cache for instance country data, currency data (base data, not rates), sales unit data (pcs, m, kg etc). These are all stored in a database but almost never change.
It is not a very good approach to use static objects. I would use something like RavenDB which can be used to store your settings or DB data in-memory. It has a very small footprint and is very fast. It has full LINQ support.

Is SqlDataSource created for each client that connects to a server?

Assume I have a page with a data grid bound to a data source. If I have 2 different clients accessing this page, is the data source different for each of them, or do they use the same data source?
If they're the same, what happens if a client applies a filter? The other clients sees that filter too? How to avoid this?
If they're not the same, and I have a big number of records, and data source mode is to DataSet, would this store 2 copies of same data on server? How do I solve such problems?
The SqlDataSource control is an instance class, so it would be recreated on each request. You may want to look into connection pooling though, so you can reuse database connections.
I don't think it's possible to make the control static, and I don't think you need to make the control static. If you want to reuse the dataset for all users who visit the page, I would look into caching the DataSet, or storing it in application state. I believe you can do this with the SqlDataSource using a mixture of the OnSelecting and OnSelected events.
Cache the DataSet in the OnSelected event
In the OnSelecting event, check to see whether you have a cached DataSet, and cancel the the select if you do.
They are separate unless you have made the Dataset static, then it will be shared across all instances of the page. I'm not sure what problem you are trying to solve exactly? Is there no database behind the dataset? Or are you worried about the memory consumption?

Updating a SQL database table with a webservice

I have an issue and I have looked long and hard over the Internet for an answer but cant find anything.
I have a little app that sucks in a web service. It then passes this web services results another applications via its own web service and stores the request in a table.
What I am trying to do is quickly import the results to a table from the data set.
Option 1 is that I loop through all the rows in the data set and use an insert on each. The issue with this is it is slow and will slow down the response of the little apps web service.
Option 2 is to bulk upload the data set into sql. The bad news for me is I have no idea of how to do this!! Can any one help?
You can use SqlBulkCopy. A simple SqlBulkCopy might look like:
DataTable dtMyData = ... retrieve records from WebService
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString)) {
bulkCopy.BulkCopyTimeout = 120; // timeout in seconds, default is 30
bulkCopy.DestinationTableName = "MyTable";
bulkCopy.WriteToServer(dtMyData);
}
If you are processing a great deal of data you may also want to set the BatchSize property.
It sounds like a mighty busy little web service.
You might instead (or even in addition) consider making it asynchronous or multi-threaded. Otherwise you've just built in the coupling between the two web apps that you may have split them to avoid in the first place.
Using a bulk load can be a pain for various reasons, starting with that how you do it is specific to a particular DBMS. (The next thing that usually gets you is where the file with the data needs to be located.)
However, you can often improve performance dramatically in a portable way merely by doing all of your INSERTs in a single transaction:
BEGIN TRANSACTION
INSERT ...
INSERT ...
...
COMMIT TRANSACTION
If time is on your side, you could look into using SQL Server Service Broker technology however there is initially quite a steep learning curve.
http://msdn.microsoft.com/en-us/library/ms166043(SQL.90).aspx
You can create a web service that fires say a stored procedure to insert the results of your process.

Resources