I have a database in which I return information about several entities in a single free text search, here is an example database:
dbo.Electrician
ElectricianId | Company | TelNo | Mobile | Addr1 | Postcode
123 | Sparky 1 | 01234567 | 0789078 | 42 lower ave | Ex2345
124 | Sparky 2 | 01235678 | 0777777 | 1 Street | Ta6547
125 | Sparky 3 | 05415644 | 0799078 | 4 Air Road | Gl4126
dbo.Painters
PainterId | Company | TelNo | Mobile | Addr1 | Postcode
333 | Painter 1 | 01234568 | 07232444 | 4 Higher ave | Ex2345
334 | Painter 2 | 01235679 | 07879879 | 5 Street | Ta6547
335 | Painter 3 | 05415645 | 07654654 | 5 Sky Road | Gl4126
dbo.Clients
ClientId | Name | TelNo | Mobile | Addr1 | Postcode
100333 | Mr Chester | 0154 5478 | 07878979 | 9 String Rd | PL41 1X
100334 | Mrs Garrix | 0254 6511 | 07126344 | 10 String Rd | PL41 1X
100335 | Ms Indy Pendant | 0208 1154 | 07665654 | 11 String Rd | PL41 1X
My current method is working as such:
Create Temp Table (EntityId, DisplayName, LongName, EntityType)
Take search terms and replace unwanted characters before replacing spaces with commas and using this as a CSV.
SET @searchTerms = LTRIM(RTRIM(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(LTRIM(RTRIM(@searchTerms)), ',', ' '),
'[', ''),
']', ''),
'#', ''),
'&', ''),
';', ''),
'?', ''),
'`', ''),
'''', ''),
'*', ''),
'"', ''),
'<', ' '),
'>', ' '),
'-', ' '),
'(', ' '),
')', ' '),
'', ' '),
'/', ' ')))
SET @searchTerms = REPLACE(@searchTerms, ' ', ',')
DECLARE @SearchTerm AS nvarchar(50);
DECLARE @DevelopmentCursor AS CURSOR;
SET @DevelopmentCursor = CURSOR
FOR
SELECT
*
FROM general.Csvtoquery(@searchTerms)
WHERE value != ''
Next I loop over my search terms inserting each entity into my Temp table:
INSERT INTO #tempsearchtable (EntityId, Name, LongName, EntityType)
SELECT
tc.ClientId,
tc.Title + ' ' + tc.FirstName + ' ' + tc.LastName,
tc.Title + ' ' + tc.FirstName + ' ' + tc.LastName + ', ' + COALESCE(a.NameOrNumber, '') + ', ' + COALESCE(a.Street, '') + ', ' + COALESCE(a.Town, '') + ', ' + + ', ' + COALESCE(a.County, '') + ', ' + COALESCE(a.Postcode, '') + ', ' + COALESCE(a.Country, '') + ', ' + COALESCE(tc.EmailAddress, '') + ', ' + COALESCE(REPLACE(tc.Telephone, ' ', ''), '') + ', ' + COALESCE(REPLACE(tc.Mobile, ' ', ''), ''),
'Client'
FROM
dbo.Clients tc
LEFT JOIN
dbo.[Address] a ON tc.AddressId = a.AddressId
WHERE
tc.FirstName LIKE '%' + @SearchTerm + '%'
OR tc.LastName LIKE '%' + @SearchTerm + '%'
OR tc.EmailAddress = @SearchTerm
OR REPLACE(tc.Telephone, ' ', '') LIKE '%' + @SearchTerm + '%'
OR REPLACE(tc.Mobile, ' ', '') LIKE '%' + @SearchTerm + '%'
OR a.NameOrNumber LIKE '%' + @SearchTerm + '%'
OR a.Street LIKE '%' + @SearchTerm + '%'
OR a.Postcode LIKE '%' + @SearchTerm + '%'
OR a.County LIKE '%' + @SearchTerm + '%'
OR a.Town LIKE '%' + @SearchTerm + '%'
OR a.Country LIKE '%' + @SearchTerm + '%'
I now loop my searches again. This is to ensure I am only getting specific matches. I delete anything where the LongName doesn't contain my search term.
I select all from the temp table before dropping it.
While this does work, and works pretty well, the search is slower than I'd like and I was looking for suggestions to speed this up. One of which was to create an index table and dump all the entities into this, and just have 1 loop getting the specific searches. This is slightly faster but it also means I only have data for when the last task was set to dump the data into the index. Live searches are imperative.
Thanks for any suggestions.
See Question&Answers more detail:os