The problem is just the sheer amount of Category and Product data that I'm dealing with. There are approximately 3000 Categories, and almost 10000 Products.
The behaviour I was seeing was this:
- The CategoryList control, which loaded on every page, would call DSC_Category_Get for all Categories and at all Levels.
- For each level, DSC_Category_GetByTempTable is called
- For each category inside this proc, DSC_Category_GetParentFullPath is called.
- Inside this proc, DSC_Category_GetParents is called
- DSC_Category_GetParents recursively gets the parents of every category, then returns an in-memory table of the results
- When looking at the SQL Profiler logging just Stored Procedure calls, I was seeing over 5000 rows per page hit. With a couple of users on the site, I was seeing hundreds of thousands per minute, and database operations started blocking because there was a backlog since SQL Server couldn't keep up.. And this is a very powerful server.
The result of most of this work is to get the ParentFullPath, CategoryCount and the HasChildren flag for each category.. But this information is relatively static and certainly does not have to be retrieved on every page hit (Especially considering 99% of the pages on the site have the CategoryList in a disabled LeftMasterBlock and it never gets shown to the user!).
Because after hours of searching, changing and debugging, I still couldn't find a reliable way to refrain from loading the CategoryList if the LeftMasterBlock is disabled, I decided to just optimize the DSC_Category_GetByTempTable proc. I added ParentFullPath, CategoryCount and HasChildren columns right to the Category table, and just update them periodically through a SQL job. The proc now just does a simple join between Category and the #subset_Category temp table.. So my number of executions of stored procs per page hit have now dropped from 5000 per page, to around 50.. And the performance improvement of the site now makes it usable. ;)
|