Is there any performance difference between the following?
NAME LIKE '%EXPRESSION_1%'
OR NAME LIKE '%EXPRESSION_2%'
...
OR NAME LIKE '%EXPRESSION_N%'
VS
NAME IN (ACTUAL_VALUE_1,ACTUAL_VALUE_2,.., ACTUAL_VALUE_N)
The IN version is potentially much, much faster.
The two versions do not do the same thing. But, if either meets your needs, the IN version can take advantage of an index on NAME. The LIKE version cannot, because the pattern starts with a wildcard.
You could write this as:
WHERE NAME LIKE 'EXPRESSION_%'
If this meets your needs, it can also take advantage of an index on NAME.
You can simply try to use
NAME LIKE '%EXPRESSION_%'
As far as the performance is concerned then IN is comparatively faster than OR. Also you can confirm the performance using the execution plan of your two queries.
Also as commented above, the two queries which you are showing are different.
The first query:
NAME LIKE '%EXPRESSION_1%'
OR NAME LIKE '%EXPRESSION_2%'
...
OR NAME LIKE '%EXPRESSION_N%'
will try to fetch the result which has sample data like
EXPRESSION_123
XXXEXPRESSION_1234
EXPRESSION_2323
EXPRESSION_2......
whereas your second query will match the records which are exactly matching to
ACTUAL_VALUE_1,ACTUAL_VALUE_2.....
If you are using variable expression which can be change according to the given parameter. Then use of
declare #Expression1 varchar(50)
Set #Expression2 = '%'+ #Expression1 +'%'
NAME LIKE #Expression2
so whatever parameter will come in #Expression1 it will automatically take care of it.
Related
Looking at this link: SQL SELECT LIKE
What if you were searching for a name that starts with H and ends with dinger?
Would I use:
SELECT NAME LIKE
'H_dinger'
'H...dinger' or
'H%dinger' ?
I'll assume H_dinger would think there is only 1 character in between, but I don't know what it is -- so I'm searching for it.
H...dinger isn't valid.
And H%dinger seems like it would check it all, but on the site, that isn't even listed?
You would use %, which is the variable-sized wildcard.
But you need to get the syntax right, such as with:
select NAME from TABLE where NAME like 'H%dinger'
Keep in mind that queries using % may be a performance issue (depending on how it's used and the DBMS engine). It can prevent the efficient use of indexes to speed up queries. It probably won't matter for small tables but it's something to keep in mind if you ever need to scale.
Assume mytable is an Oracle table and it has a field called id. The datatype of id is NUMBER(8). Compare the following queries:
select * from mytable where id like '715%'
and
select * from mytable where id between 71500000 and 71599999
I would think the second is more efficient since I think "number comparison" would require fewer number of assembly language instructions than "string comparison". I need a confirmation or correction. Please confirm/correct and throw any further comment related to either operator.
UPDATE: I forgot to mention 1 important piece of info. id in this case must be an 8-digit number.
If you only want values between 71500000 and 71599999 then yes the second one is much more efficient. The first one would also return values between 7150-7159, 71500-71599 etc. and so forth. You would either need to sift through unecessary results or write another couple lines of code to filter the rest of them out. The second option is definitely more efficient for what you seem to want to do.
It seems like the execution plan on the second query is more efficient.
The first query is doing a full table scan of the id's, whereas the second query is not.
My Test Data:
Execution Plan of first query:
Execution Plan of second query:
I don't like the idea of using LIKE with a numeric column.
Also, it may not give the results you are looking for.
If you have a value of 715000000, it will show up in the query result, even though it is larger than 71599999.
Also, I do not like between on principle.
If a thing is between two other things, it should not include those two other things. But this is just a personal annoyance.
I prefer to use >= and <= This avoids confusion when I read the query. In addition, sometimes I have to change the query to something like >= a and < c. If I started by using the between operator, I would have to rewrite it when I don't want to be inclusive.
Harv
In addition to the other points raised, using LIKE in the manner you suggest would cause Oracle to not use any indexes on the ID column due to the implicit conversion of the data from number to character, resulting in a full table scan when using LIKE versus and index range scan when using BETWEEN. Assuming, of course, you have an index on ID. Even if you don't, however, Oracle will have to do the type conversion on each value it scans in the LIKE case, which it won't have to do in the other.
You can use math function, otherwise you have to use to_char function to use like, but it will cause performance problems.
select * from mytable where floor(id /100000) = 715
or
select * from mytable where floor(id /100000) = TO_NUMBER('715') // this is parametric
I would like to create a SQL query, which does the following..
- I have a few parameters, for instance like "John","Smith"
- Now I have a articles tables with a content column, which I would like to be searched
- Now, How can I find out the rows in the articles table, which has the any one of those values("John","Smith")
I cannot use content LIKE "%john% or content LIKE "%smith%", as there could be any number of incoming parameters.
Can you guys please tell me a way to do this....
Thanks
Have you considered full-text search?
While HLGEM's solution is ideal, if full-text search is not possible, you could construct a regular expression that you could test only once per row. How exactly you do that depends on the DBMS you're using.
This depends a lot on the DBMS you're using. Generally - if you don't want to use full-text search - you can almost always use regular expressions to achive this goal. For MySQL see this manual page - they even have example answering your question.
If full text search is overkill, consider putting the parameters in a table and use LIKE in theJOIN` condition e.g.
SELECT * -- column list in production code
FROM Entities AS E1
INNER JOIN Params AS P1
ON E1.entity_name LIKE '%' + P1.param + '%';
I was curious since i read it in a doc. Does writing
select * from CONTACTS where id = ‘098’ and name like ‘Tom%’;
speed up the query as oppose to
select * from CONTACTS where name like ‘Tom%’ and id = ‘098’;
The first has an indexed column on the left side. Does it actually speed things up or is it superstition?
Using php and mysql
Check the query plans with explain. They should be exactly the same.
This is purely superstition. I see no reason that either query would differ in speed. If it was an OR query rather than an AND query however, then I could see that having it on the left may spped things up.
interesting question, i tried this once. query plans are the same (using EXPLAIN).
but considering short-circuit-evaluation i was wondering too why there is no difference (or does mysql fully evaluate boolean statements?)
You may be mis-remembering or mis-reading something else, regarding which side the wildcards are on a string literal in a Like predicate. Putting the wildcard on the right (as in yr example), allows the query engine to use any indices that might exist on the table column you are searching (in this case - name). But if you put the wildcard on the left,
select * from CONTACTS where name like ‘%Tom’ and id = ‘098’;
then the engine cannot use any existing index and must do a complete table scan.
So I have a stored procedure that accepts a product code like 1234567890. I want to facilitate a wildcard search option for those products. (i.e. 123456*) and have it return all those products that match. What is the best way to do this?
I have in the past used something like below:
SELECT #product_code = REPLACE(#product_code, '*', '%')
and then do a LIKE search on the product_code field, but i feel like it can be improved.
What your doing already is about the best you can do.
One optimization you might try is to ensure there's an index on the columns you're allowing this on. SQL Server will still need to do a full scan for the wildcard search, but it'll be only over the specific index rather than the full table.
As always, checking the query plan before and after any changes is a great idea.
A couple of random ideas
It depends, but you might like to consider:
Always look for a substring by default. e.g. if the user enters "1234", you search for:
WHERE product like "%1234%"
Allow users full control. i.e. simply take their input and pass it to the LIKE clause. This means that they can come up with their own custom searches. This will only be useful if your users are interested in learning.
WHERE product like #input