Caching Key Generation Considerations

Posted by: Steven Smith, on 25 Aug 2009 | View original | Bookmarked: 0 time(s)

Recently I was reviewing some code and ran across this can you spot the problem?

var parameters = new List<SqlParameter>
     {
        new SqlParameter("@SomeID", someId), 
        new SqlParameter("@SomeOtherID", someOtherId), 
        new SqlParameter("@ServerDate", serverTime)
                                };
      string cacheKey = string.Format("ResultSetName-sid{0}-soid{1}-date{2}",
                                  parameters.Select(x => x.Value).ToArray()); 
      var resultSet = Cache[cacheKey] as List<Foo>;
      if (resultSet == null)
      {
      // do stuff and add resultSet to cache with cacheKey
      }

 

There are actually a couple of different issues with this approach.  The first one is that the serverTime parameter is literally sending in the current time (not date), which means that when it is .ToString()d and joined into the cacheKey, its going to have information down to the second.  Since this method is being called several times per second, that just means that there is going to be a new cache entry every second as a result of the choice of cache key. Whats worse, the old items wont automatically be purged since there isnt any 1-second absolute expiration here, so the ASP.NET Cache has to use its standard LRU algorithm to clean things up when it starts feeling memory pressure (which will probably happen pretty quickly).  End result, a fair bit of needless thrashing and memory usage.

Thats the main problem, and in some performance tests using CacheManager I saw the total number of cache entries for the application reach up to six figures with this code in place.  The simplest fix that retains the date parameter is to change the 3rd SqlParameter line to use serverTime.ToShortDateString() which ensures the key only varies by date and not by second, resulting in  86,399 fewer cache entries per day per other variation in the key.

The other question of course is why the date is in the key at all?  If you really want the key to expire frequently, thats what AbsoluteExpiration cache dependencies are for, and these will automatically clean up (or at least mark as ready to clean up) the expired entries, rather than just widowing their keys and leaving it up to the Caches memory management to take care of the mess.  In general, dates make a poor choice for inclusion in cache keys, and raw datetimes are especially a bad idea.

Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: SQL | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 863 | Hits: 11

Similar Posts

  • 4 Settings To Improve DevExpress ASP.NET Performance more
  • Swivel Behavior in Silverlight 3 more
  • Are you mouse-bored? more
  • ORM Release History : Q2 2009 (2009.2.701.5) more
  • XAML By FARR: Animations, Resources Vs. Code Behind more
  • SQL SERVER Difference Between Candidate Keys and Primary Key more
  • Keep the Customer Satisfied (Matt Gertz) more
  • Quick 3-d Update more
  • Automated Attendant with the OCSDK Wrapper and WPF more
  • Foundations of Programming - pt 9 - Proxy This and Proxy That more

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD