Integrity Over Profit
Simple ways
to drastically increase application performance
Increased application performance creates multiple monetary advantages for your business.
First, you will spend less money on servers.
Second, you spend less money paying developers to spend time researching and fixing performance issues.
Third, fast applications contribute to user and customer loyalty.
Below are some of the performance enhancement methods I have collected over the years and now use in every web application I build. Most of these enhancement methods are pretty standard, so you will be able to find a lot more information about them on the web if you need to do more research.
Use stored procedures for all database access
Using stored procedures allows your database to cache query execution plans and this alone can drastically increase application performance. Using stored procedures also reduces network traffic because your web server only has to send the stored procedure name and variables to your database server instead of all of the query text.
Use fully qualified names when calling your stored procedures
This increases the likelihood that your database will use a cached query execution plan to execute your query.
Use the SET NOCOUNT ON statement in queries
This keeps the database server from sending you back the number of rows affected by your query, thus reducing network traffic.
Use table locking hints in all your database queries
For Sql Server this means using WITH (NOLOCK) in SELECT statements and WITH (ROWLOCK) in UPDATE and DELETE statements. You will almost certainly realize drastic performance improvements by implementing this method. There are very few scenarios where you will not want to use these table hints, but I will leave it to you to learn more about database locking to determine what those scenarios are for your application.
Always use read-only, forward-only recordsets when reading data from your database
If you need to know the recordcount before you begin processing the recordset, return it as a field in your recordset. This can drastically improve performance when implemented throughout your application.
Use stateless, static classes in your data access layer
Given that all your data access layer should be doing is calling stored procedures and passing back data, there is no reason for your application to have to set aside extra memory for every call to your database.
Paginate in your database layer
In cases where it is necessary for your data to be paginated in the display layer, you should never paginate above the database layer. This means that the stored procedure that is returning the data to be paginated should take a @startIndex variable and an @endIndex variable, and making use of ROW_NUMBER (or the like if not using Sql Server) and a subquery, return only the records needed by the application. Using this method can drastically increase application performance and the performance gains become more pronounced over time as your database grows in size.
Use .js includes for all of your javascript
This allows the user’s browser to cache your javascript so that it does not have to be downloaded every time a page is requested. I use a global.js file that is included on every page for utility functions that are used ubiquitously in my applications and each page that has supporting javascript has its own .js include.
SessionXml
A few years ago I decided that I needed to come up with a way to keep from having to make database requests for data that was fairly static, but was included on the majority of pages, such as a user’s username. However, I also needed this new method to be stateless because I didn’t want to allocate memory to store the data and I also needed my applications to scale to multiple web servers when necessary. Thus SessionXml was born. SessionXml works by saving the frequently used, fairly static data to an Xml file on the web server and storing a SessionKey in a cookie to the user’s machine that tells the application where to find the SessionXml file. Each place in the application that uses the SessionXml first looks for the node(s), and if it doesn’t find them, queries the database and saves the node(s) to the SessionXml file for future use. That way, when the data is updated, all I have to do is delete the node(s) that contained the data from the SessionXml file because it will be repopulated when it is needed. Using this method can drastically increase application performance and the performance gains become more pronounced over time as your site traffic grows.
DataCache
This concept is similar to SessionXml in that it is stateless and scales to multiple web servers, except that it is used for application level data. I create a directory on my web server named DataCache. In that directory I save Xml files that contain application level data that will only potentially change on a per release basis, such as data from lookup tables. In the DataCache directory, I also save snapshots of data that is calculation intensive and I run processes on the web server at 10-15 minute intervals that refresh those Xml files. For instance, I was able to display sums and groupings from tables that contained millions of rows on the homepage of one of our applications with a drastic performance increase versus querying the database each time the page was loaded using this method.
Page reloads = bad
When you reload a page just to update a part of the page, you are creating unnecessary load on every part of your application from the network traffic between the user and web server down to the database. The most pronounced advantaged of building your application with a componentized architecture is that since the different parts of your page are already implemented as separate components, it is very easy to load only the part that needs to be updated because that methodology is baked into your architecture. This means that using a componentized architecture literally increases performance on every layer of your application for the vast majority of the hundreds of thousands or millions of requests. Taken together, this translates into a tremendous performance increase. The underpinnings of my method for doing this include asynchronous XMLHTTP javascript, a Servers directory that has nothing in it but pages that serve components, and lots of Xml and Xslt.