To help explain my question I’ll explain a little bit of the problem. We have a database of customers, including a history of their addresses (i.e. every address update inserts a new row into the address table and we have views that pull the latest information for reporting on screen and printed reports).
User requirement for a new search is that we show their current address (if we have one on file) on search results to determine that they are indeed finding the correct client.
We have reached a performance hit by running a left join to a view in our returned search results, so this is where the question comes in.
Our first thought was to store a copy of the latest address for display only purposes in our customer table, but we were concerned at how to keep this data updated. We wondered if a computed column could be built on a scalar function to query our view and have it persisted, or if triggers were our only option.
Am I barking up the wrong tree entirely by looking at ways of getting around this slowness, should I be investigating addressing the database tuning in some way to optimize the search instead?
Thanks in advance,
Wesley
edit: query is as shown:
Select
Clients.ClientID,
Clients.LastName,
Clients.FirstName,
Clients.PreferredName,
PrimaryDeliveryCity as City,
PrimaryDeliveryPostalCode as PostalCode,
DateOfBirth,
ClientNumber
FROM
Clients LEFT JOIN v_LatestClientAddressHistoryRecord
ON Clients.ClientID = v_LatestClientAddressHistoryRecord.ClientID
WHERE
ClientNumber like @ClientNumber + '%'
Indeed the query does have %, however not on the joined table.
Clients has 50,000 records, view has similar but slightly less, base address table has 200,000
Edit #2:
SELECT ClientAddressHistoryRecords.*
FROM
dbo.ClientAddressHistoryRecords INNER JOIN dbo.v_LatestClientAddressHistoryRecordID
ON dbo.ClientAddressHistoryRecords.ClientID = dbo.v_LatestClientAddressHistoryRecordID.ClientID
AND
dbo.ClientAddressHistoryRecords.ClientAddressHistoryRecordID = dbo.v_LatestClientAddressHistoryRecordID.MaxClientAddressHistoryRecordID
and the v_LatestClientAddressHistoryRecordID view
SELECT MAX(ClientConsentHistoryRecordID) AS MaxClientConsentHistoryRecordID, ClientID
FROM dbo.ClientConsentHistoryRecords
GROUP BY ClientID
Another approach would be an
INSTEAD OF TRIGGERthat inserts all inserts/updates into a history table (each as its own row), and merges all inserts/updates into an active table (with the only row for a customer being the most current row). Now you point your active queries at the active table, and if you need the history, you write that query to go fetch it from the archive table. Yes, you have two copies of the active rows, but assuming the speed issue is due to there being a large % of old addresses sticking around, this might be ok.