Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing Oracle CONNECT BY when used with WHERE clause

Oracle START WITH ... CONNECT BY clause is applied before applying WHERE condition in the same query. Thus, WHERE constraints won't help optimize CONNECT BY.

For example, the following query will likely perform full table scan (ignoring selectivity on dept_id):

SELECT * FROM employees 
WHERE dept_id = 'SALE'
START WITH manager_id is null
CONNECT BY PRIOR employee_id = manager_id

I tried to improve performance in 2 ways:

query A:

SELECT * FROM employees 
START WITH manager_id is null AND dept_id = 'SALE'
CONNECT BY PRIOR employee_id = manager_id

query B:

SELECT * FROM (
               SELECT * FROM employees 
                WHERE dept_id = 'SALE'
              )
START WITH manager_id is null
CONNECT BY PRIOR employee_id = manager_id

While both queries did much better than original, on Oracle 10g Release 2, query B did performed much better than A.

Did you have similar performance optimization to deal with with respect to CONNECT BY and WHERE clauses? How would you explain query B doing much better than query A?

like image 562
topchef Avatar asked Jul 04 '09 05:07

topchef


People also ask

Does where clause improve performance?

A where clause will generally increase the performance of the database. Generally, it is more expensive to return data and filter in the application. The database can optimize the query, using indexes and partitions. The database may be running in parallel, executing the query in parallel.

Does with clause improve performance in Oracle?

The Oracle "with" clause will help performance in situations where your query contains several identical sub queries. Instead of re-computing the repeating sub queries, it will query or aggregate once, assign a name to the resulting data and refer to it.

How do I make my Oracle query run faster?

Partitioning your data and creating local partitioned indexes can improve your query performance. On a partitioned table, each partition has its own set of index tables. Effectively, there are multiple indexes, but the results from each are combined as necessary to produce the final result set.

Can we use having and where clause together in Oracle?

Introduction to the Oracle HAVING clause In this statement, the HAVING clause appears immediately after the GROUP BY clause. If you use the HAVING clause without the GROUP BY clause, the HAVING clause works like the WHERE clause. Note that the HAVING clause filters groups of rows while the WHERE clause filters rows.


2 Answers

Query A says start with managers in the Sales department and then get all their employees. Oracle doesn't "know" that all the employees returned be the query will be in the Sales department, so it can't use that information to reduce the set of data to work with before performing the CONNECT BY.

Query B explicitly reduces the set of data to be worked on to just those employees in Sales, which Oracle can then do before performing the CONNECT BY.

like image 66
Tony Andrews Avatar answered Oct 08 '22 23:10

Tony Andrews


This should give the ultimate performance:

CREATE INDEX i_employees_employee_manager_dept ON employees (employee_id,manager_id,dept_id);
CREATE INDEX i_employees_manager_employee_dept ON employees (manager_id,employee_id,dept_id);

SELECT * FROM employees  
START WITH manager_id is null AND dept_id = 'SALE' 
CONNECT BY PRIOR employee_id = manager_id AND dept_id = 'SALE' 

Note that you do need both index and both AND conditions for the optimization to work.

like image 34
jluu Avatar answered Oct 09 '22 00:10

jluu