I am building a web-store with many departments and categories. They are stored in our database and accessed often.
We are using URL rewriting so almost every request within the store generates a lookup. We also need to iterate over the data frequently to generate menus for the main store and the department pages.
This information will not change often so I'm thinking that I should load the database into a dictionary to speed up the information retrieval.
I know the standard practice is to load data into the application cache, however i assume that there is some level of serialization that occurs during caching, and for a large data-structure I'm thinking the overhead would be significant.
My impulse on this is to put the dictionary in a static variable in one of the related classes. I would however like to get some input input on this. Am I right in thinking that this method would be faster? Is it horrible practice? Is there a better way that I'm missing?
I can't seem to find much information on this and I'd really appreciate any information that you can share. Thanks!
The Application and Cache collections do not serialize the objects you pass into them, they store the actual reference. Retrieving an object from Cache will not be an expensive operation, no matter how large the object is. Always stick with the Cache objects unless you have a very good reason not to, its just good practice.
The only other thing worth mentioning is to make sure you think about multithreaded access to this collection. You're going to end up with some serious issues very quickly if you don't lock properly
Well, I don't think it's so much work to rewrite code to use a static field instead of application cache if there's need to do so. I'd personally use the cache first. There's no need for premature optimization, have you measured the performance? It may behave just right with the application cache object. Maybe it even works well with db queries? :)
So, my answer is - use the cache and see how it works.
memcached is your friend! (but could be overkill if you're not scaling out)
Any idea how large your dictionary would be in application cache? I'd be tempted to recommend that as a good first option.
IMHO, generally speaking, if you have control on updates on underlying object, you should use static storage. Otherwise, if you are dependent on a 3rd party API for data retrievals, use Caching technology.
Related
i have a similar requirement to stackoverflow to show a number of metrics on a page in my asp.net-mvc site that are very expensive to calculate. Stackoverflow has a lot of metrics on the page (like user accept rate, etc) which clearly is not being calculated on the fly on page request, given that it would be too slow.
What is a recommended practice for serving up calculated data really fast without the performance penalty (assuming we can accept that this data maybe a little out of date.
is this stored in some caching layer or stored in some other "results" database table so every day there is a job to calculate this data and store the results so they can be queries directly?
assuming that i am happy to deal with the delayed of having this data as a snapshot,what is the best solution for this type of problem.
Probably they may be relying on the Redis data store for such calculations and caching. This post from marcgravell may help.
yes, the answer is caching, how you do it is (can be) the complicated part, if you are using NHibernate adding caching is really easy, is part of your configuration and on the queries you just add .Cacheable and it manages it for you. Caching also depends on the type of environment, if you're using a single worker, web farm or web garden, you would have to build a caching layer to accomodate for your scenario
Although this is a somewhat-recent technique, one really great way to structure your system to make stuff like this possible is by using Command and Query Responsibility Segregation, more often referred to by CQRS.
This might be a silly question? but are you able to perform a SQL query to the database to get all record items for X, store it into a local variable "myRecords" and then filter our the results contained in "myRecords" variable? (Saves you making multiple rounds/queries to the database).
Is this even a good idea? or a bad idea?
I believe you referring to classic case of caching, there are plenty of resources to guide you though the implementation of such approach. To get more specific answer you will need to give more details of the problem you are trying to solve. The topic is huge and could be very complex depending on the parameters of your environment.
Definitely!! Its called caching.. but so many different ways to do it.. check out this great article http://wiki.asp.net/page.aspx/655/caching-in-aspnet/
I agree with K Ivanov. Just wanted to add a few things.
This can be a huge performance improvement or a complete disaster. Rarely is it in the middle of the two.
I think you might want to do a few things before pursuing this topic. First, profile your database and queries. Look for any areas such as new or changed indexes or even a slightly different table design that might lead to performance improvements first.
There are several problems. The first deals with memory requirements on the machine that will cache this. If your database server is already memory constrained then adding some intermediary cache ON it is not advisable.
If you cache the data in the web server then you might be radically increasing the memory footprint of your application. Further, depending on the caching strategy and the nature of your data it can quickly become stale leading to bad results.
Point is, before you try and go a different path make sure you completely understand the problem you have. It might be as simple as tweaking indexes and/or adding RAM to your DB server. These are relatively easy to implement whereas a solid caching mechanism can either be a boon or lead to even larger problems.
I've written my own caching layer for my objects that come out of data access. My reasoning here is I'd like my data access layer to do just that -- data access. I don't really want it to worry about caching, and I'd only like to go in to that layer when I need to fetch data out of the database. Perhaps this is not the right way to think about things -- please let me know if I'm off track.
Anyway, there is at least one issue that I've ran in to so far. In one scenario, I load an object from NHibernate and stick it in the cache in one request. In the next request I get that object from the cache, modify it, and go back down to NHibernate to save it. Obviously NHibernate pukes, in this particular instance with a "Illegal attempt to associate a collection with two open sessions" exception.
So my question is, I guess, is there anything I should be aware of or do to make this work? Or should I just use a 2nd level cache that's built in to NHibernate?
NHibernate has caching for a reason.. use it :)
You'll find there are quite a few options for a second level cache provider that give you much more flexibility for cheaper then you could build it yourself. A perfect example is something like memcache if you decide you need to run a service on multiple systems.
Currently, my entire website does updating from SQL parameterized queries. It works, we've had no problems with it, but it can occasionally be very slow.
I was wondering if it makes sense to refactor some of these SQL commands into classes so that we would not have to hit the database so often. I understand hitting the database is generally the slowest part of any web application For example, say we have a class structure like this:
Project (comprised of) Tasks (comprised of) Assignments
Where Project, Task, and Assignment are classes.
At certain points in the site you are only working on one project at a time, and so creating a Project class and passing it among pages (using Session, Profile, something else) might make sense. I imagine this class would have a Save() method to save value changes.
Does it make sense to invest the time into doing this? Under what conditions might it be worth it?
If your site is slow, you need to figure out what the bottleneck is before you randomly start optimizing things.
Caching is certainly a good idea, but you shouldn't assume that this will solve the problem.
Caching is almost always underutilized in ASP .NET applications. Any time you hit your database, you should look for ways to cache the results.
Serializing objects into the session can be costly in itself, but most likley faster than just hitting the database every single time. You are benefiting now from Execution Plan caching in SQL Server so it's very likely that what you're getting is optimal performance out of your stored procedure.
One option you might consider doing to increase performance is to astract your data into objects via LINQ to SQL (against your sprocs) and then use AppFabric to cache the objects.
http://msdn.microsoft.com/en-us/windowsserver/ee695849.aspx
As for your updates, you should do that directly against the sprocs, but you will also need to clear our the Cache in AppFabric for objects that are affected by the Insert/Update/Delete.
You could also do the same thing simply using the standard Cache as well, but AppFabric has some added benefits.
Use the SQL Profiler to identify your slowest queries, and see if you can improve them with some simple index changes (removing unused indexes, adding missing indexes).
You could very easily improve your application performance by an order of magnitude without changing your front-end app at all.
See http://sqlserverpedia.com/wiki/Find_Missing_Indexes
If you have look up data only, you can store it in Cache object. This will avoid the hits to DB. Only data that can be used globally should be stored in Cache.
If this data requires filtering, you can restore it from Cache, and filter the data before rendering.
Session can be used to store user specific data. But care must be taken that too much of session variables can easily cause performance problems.
This book may be helpful.
http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839
Say I have some 10 "categories" that I need to reference in a web app. Currently I'm storing these categories in the DB and am retrieving them (category name and id) during pageload in my basepage, storing them in a hashtable and then using the hashtable to reference the categories. I realized that the DB call is being made during each pageload. I only need to pull these categories once as they never change during a given session. What's the best way to do this?
Do whatever I am doing, but store it as a Application variable?
Hard code the categories in the code, and do away with the database?
Store the categories in a session variable? And call the DB only if the session is empty?
Or something else?
I'm just curious to know what the best-practice is for doing such things.
If the categories are user dependent then I'd store them in the Session variable; otherwise I'd use the ASP.NET Caching functionality (or preferred distributed caching). This allows you to avoid hitting the database whilst being able to control how long the categories should be cached for.
Calling the database is not always as expensive as it seems, a typical website makes dozens of calls to the DB on each pageload. But if it becomes troublesome in terms of performance, consider using an ORM solution. The excellent open source NHibernate comes to mind, which is the "de facto" standard for mapping databases to classes and objects. Beyond the mapping, it automatically provides two levels of caching and connection pooling. Without too much trouble, your website outperforms any other's by a landslide.
The downside of using an ORM? To many people, it is considered a rather steep learning curve. If you want to read into this, make sure to pay a visit to the NHibernate Best Practices. A tough read at first, but definitely worthwhile.
If you combine NHibernate with FluentNHibernate, it becomes a breeze to use.