Skip to Main Content
  • Questions
  • Explicitly providing values in a WHERE clause showing much better performance compared to using sub query

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, hama.

Asked: March 12, 2019 - 1:13 am UTC

Last updated: March 18, 2019 - 8:53 am UTC

Version: Version 4.1.3.20

Viewed 1000+ times

You Asked

Hi

I am new to oracle and not sure how to provide the liveSQL link.

I have 2 tables to join
huge_table contains about 1 billion rows
big_table contains about 100 million rows
and small tables contains 999 rows providing the condition to filter

The the small_table.num_id to match huge_table.num_id column

The problem I noticed is if I explicitly provide the values in where clauses it will be much faster compared using sub query .

Specifically when looking at the explain plan result
This query is much faster with cardinality of 100 and cost of 6
SELECT h.col_required, b.col_required, h.num_id
FROM 
huge_table h,
big_table b

WHERE h.row_id = b.xx_id
      AND b.status = 'up'
      AND h.num_id in ('num1', 'num2',... 'num100')  -- Explicitly providing the values that in 
                                                     -- small_table



This query with sub query is much slower with cardinality of 1445704 and cost of 660293


SELECT h.col_required, b.col_required, h.num_id
FROM 
huge_table h,
big_table b

WHERE h.row_id = b.xx_id
      AND b.status = 'up'
      AND h.num_id in ('SELECT num_id FROM small_table)  -- Using sub query 
                                                         -- provide the values




I also tried using WHERE exits or INNER JOIN the small_table both providing the similar result with sub query.


The question I have is if it is possible to have good performance without explicitly providing the values in where clause?


Thanks



and Chris said...

A couple of points:

- With a subquery, you have to access another table. Which is more work for the database. Though this effort should be negligible for a small table

- When you provide a list of literal values, the optimizer knows exactly which values you're searching for. Whereas with a subquery it has to guess based on the small table's stats.

This can lead to big differences in the estimates for a subquery vs. an in-list.

You have a huge difference in the estimated rows for your queries (100 vs 1445704). So you're almost certainly getting a different plan for each.

If you share the plans for the queries, we can look into this further.

For details on how to get the execution plan, see:

https://blogs.oracle.com/sql/how-to-create-an-execution-plan

Ensure this includes the E-rows, A-rows, & buffers columns!

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

hama ji, March 17, 2019 - 9:55 pm UTC

Thanks a lot for your help.

I was trying to replicate this issue again this morning. However for unknown reasons my sub-query running time greatly reduced and showing same time as When I explicitly provide the number.


Connor McDonald
March 18, 2019 - 8:53 am UTC

Ah....the dreaded datatype conversion strikes again! :-)

Thanks for getting back to us.

hama ji, March 17, 2019 - 10:54 pm UTC

Hi, I actually find out the reasons what caused the issue.

In the small_table the datatype for num_id is NVARCHAR2(255)
Whilst in the huge_table the datatype for num_id is VARCHAR2(255).

Basically after I converted the datatype the query time reduced.


More to Explore

Administration

Need more information on Administration? Check out the Administrators guide for the Oracle Database