We're using Oracle 11g database.
As you may or may not know, if you use wildcard query with "%" in front of the string, the column index is not being used and a full table scan is happening.
It looks like there isn't a definitive suggestion on how to improve this kind of query, but perhaps you could share some valuable information from your experience on how to optimize the following query:
SELECT *
FROM myTable
WHERE UPPER(CustomerName) like '%ABC%'
OR UPPER(IndemnifierOneName) like '%ABC%'
OR UPPER(IndemnifierTwoName) like '%ABC%';
...where all 3 columns are of type varchar2(100) and ABC is a value of variable input parameter.
@All suggesting CONTEX index, please note my data gets updated any time of the day every day and this index requires re-syncing, hence it's not a good option for a table of 1.5 million rows, sorry.
P.S. I'll upvote every answer, so please do keep them coming.
SQL Server Wildcard Searches Using %The first query is faster because the WHERE condition is Sargable. However, the 2nd and 3rd queries are not Sargable, hence those queries could not leverage the index on Name. As a result, the 2nd and 3rd queries are slower than the 1st query.
Indexes cannot be used with LIKE '%text%' predicates. They can, however with LIKE 'text%'.
As already mentioned you could add a ctx context index to the name columns.
assuming a small number of records get updated, 1 option is to refresh your index daily. (and record when it happened)
then add a lastupdate date column & index to your table being searched.
It should be possible to scan your ctx index for the majority of the old unchanged data and select from the small percentage of updated data using the traditonal LIKE e.g:
WHERE (lastupdated<lastrefresh AND contains(name,'%ABC%'))
OR (lastupdated>lastrefresh AND name like '%ABC%')
NOTE: you may find your query plan goes a little mental (lots of bitmap conversions to row ids) in that case split the 2 parts of the OR into a UNION ALL query. e.g
SELECT id FROM mytable
WHERE
(lastupdate>lastrefresh and name LIKE '%ABC%')
UNION ALL
SELECT id FROM mytable
WHERE lastupdate<lastrefresh and CONTAINS(name, '%ABC%', 1) > 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With