Different parameter sizes result in inefficient query plan cache usage
The profiler detected identical statements that use different sizes for the same parameters. Let us say that we issue two queries, to find users by name. (Note: I am using a syntax that will show you the size of the parameters, to demonstrate the problem).
We can do this using the following queries.
exec sp_executesql
N'SELECT * FROM Users WHERE Username = @username',
N'@username nvarchar(3)',
@username=N'bob'
exec sp_executesql
N'SELECT * FROM Users WHERE Username = @username',
N'@username nvarchar(4)',
@username=N'john'
This sort of code result in two query plans stored in the database query cache, because of the different parameter sizes. In fact, if we assume that the Username column has a length of 16, this single query may take up 16 places in the query cache.
Worse, if you have two parameters whose size change, such as username (length 16) and password (length 16), you may take up to 256 places in the query cache. Obviously, if you use more parameters, or if their length is longer, the number of places that a single query can take in the query cache goes up rapidly.
This can cause performance problems as the database need to keep track of more query plans (uses more memory) may need evict query plans from the cache, which would result in having to rebuild the query plan (increase server load and query time).
NHibernate provides the following configuration option to control this:
<property name='prepare_sql'>true</property>
After specifying this, NHibernate will generate consistent query plan for all identical queries, regardless of the actual parameter size.