I have the following query which is being executed in SQL Server 2008 R2 several times a day on multiple client databases.
UPDATE Propane.RecordKey
With (TabLock)
SET LookupKey = System.Param_RecordKey.LookupKey
FROM Propane.RecordKey INNER JOIN
System.Param_RecordKey ON
Propane.RecordKey.IndexId = System.Param_RecordKey.IndexId
And Propane.RecordKey.RecordNumber = System.Param_RecordKey.RecordNumber
AND Propane.RecordKey.LookupKey <> System.Param_RecordKey.LookupKey
WHERE (System.Param_RecordKey.ParameterKeyId = @key)
I am looking for any suggestion on how to make this query run as quickly as possible. Currently I am having delays which can last from a few seconds to a minute or more.
The performance is not consistent, with some cases where many records are affected are running relatively quickly and other cases with many fewer affected records running quite slowly. On my test machine the performance is generally acceptable (i.e a few seconds for 10,000+ records), but there is significant delays occurring on some of our clients.
This extreme variation which I am unable to account for, combined with my admittedly limited knowledge of how to tweak query performance, makes me reluctant to experiment with alterations which may not show much benefit and might make the query run worse.
The table being updated, RecordKey, is read from frequently (hundreds to thousands of times a day) and updated occasionally (a few times per day).
RecordKey's primary index is IndexId and RecordNumber. Param_RecordKey has key fields of ParameterKeyId, IndexId, and RecordNumber. I.e. I am filtering and joining on the primary key fields of both tables. All these fields are ints.
RecordKey will have hundreds of thousands to a few million records in it. Param_RecordKey will have just the records being updated. Typically Param_RecordKey will contain a few thousand records, though 10's of thousands of records are common and 100,000 or more is possible.
The LookupKey field in both tables is varchar(27). In most cases the text stored in the field will have a length between 5-10 characters. Lengths of 10-15 characters are common and lengths over 20 are rare. In the vast majority of cases the values in the respective LookUpKeys will be the same, i.e. few records will be updated. In rare cases ALL of the records will be updated.
One question I have is: Would I get better performance if I were to remove the check Propane.RecordKey.LookupKey <> System.Param_RecordKey.LookupKey? i.e. if I were to update all records and not just those with different LookupKeys. My expectation is that the time to update all the records would be greater than just updating those that have changed, but I'm uncertain this is true.
Any advice on how to improve this query would be greatly appreciated.
April 9th 2013, New info.
After removing the With (TabLock) and testing the changes at the client's site, the results are mixed. In some cases the query executed much faster, in some cases much slower, and in many cases there was no significant change in how long it took to process the records.
Since making the change did not result a significant and repeatable improvement in performance, I'm leaving this question open and marked as unanswered. I am still interested in any assistance with this problem.