1

I have the below query in ORACLE which takes a really long time to run because of the OR in between the 2 likes.

select pat_mrn_id,surgery_date, proc_name  
from or_log_all_proc, or_proc, or_log, patient
where 
upper(proc_name) like ('%CRANIOTOMY ANEURYSM%') OR upper(proc_name) like 
('CLIPPING%ANEURYSM')

Any help in writing the query efficiently would be appreciated. Thanks! JH

1
  • It's not the OR that's the expensive part of the WHERE clause. It's the 'LIKE '%anything%'. To solve that first condition every row in the database needs to be scanned. Try it with just the first condition and I doubt the performance will improve much at all. (Even after you fix the problem that you're cross joining 4 tables, as per the answers below) Commented Mar 18, 2019 at 17:46

4 Answers 4

3

from or_log_all_proc, or_proc, or_log, patient

Your SELECT contains no join criteria so it's going to generate a product of all the records from three of those tables and the result set of whichever table is filtered by the LIKE clauses. That is the root of your performance issue.

The solution is quite simple. Join the tables correctly using the appropriate key columns.

Incidentally this is a benefit of using the ANSI 92 join syntax. By making the type of join explicit we have to actually write CROSS JOIN if we really do want to generate a product, and prevents us from doing it accidentally.

Expecting LIKE '%anything%' to be quick is also futile

Up to a point. Most likely it's a Full Table Scan, but it's an indexed column then we might get a Full Fast Scan. Even if it is just an FTS that's not necessarily catastrophic, especially if the table is small or narroe. As with most tuning tasks, it really depends on the details.

Sign up to request clarification or add additional context in comments.

2 Comments

Expecting LIKE '%anything%' to be quick is also futile, regardless of the OR. (But your point about the cross joins is much more pertinent).
@MatBailie - yeah, maybe. If it's a small table or an indexed column then it might be okay.
2

Instead of LIKE, use regular expressions. But more importantly, you are missing JOIN conditions:

select pat_mrn_id,surgery_date, proc_name  
from or_log_all_proc join
     or_proc
     on ???? join
     or_log
     on ????
     patient
     on ????
where regexp_like(upper(proc_name), '(CRANIOTOMY ANEURYSM)|(CLIPPING.*ANEURYSM)');

It is much more likely that the performance issue is due to the lack of JOIN conditions than the LIKE.

Comments

0

LIKE will be slow anyway, won't it? Though, if you're sure that it is OR that causes problems, try UNION, e.g.

select pat_mrn_id,surgery_date, proc_name  
from or_log_all_proc, or_proc, or_log, patient
where upper(proc_name) like ('%CRANIOTOMY ANEURYSM%')
union all
select pat_mrn_id,surgery_date, proc_name  
from or_log_all_proc, or_proc, or_log, patient
where upper(proc_name) like ('CLIPPING%ANEURYSM')

Also, I guess that this isn't query you really use - there are 4 tables in the FROM clause, without any joins - a Cartesian product isn't the best choice.

Comments

0

Try union all instead of or for better performance

 select pat_mrn_id,surgery_date, proc_name  
 from or_log_all_proc, or_proc, or_log, patient
 where 
 upper(proc_name) like ('CLIPPING%ANEURYSM')
 union all     
 select pat_mrn_id,surgery_date, proc_name  
 from or_log_all_proc, or_proc, or_log, patient
 where upper(proc_name) like ('%CRANIOTOMY ANEURYSM%')

Also I think you forgot to connect the tables using unique IDs

1 Comment

Thank you all. Both Union and regexp_like worked great.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.