Oracle uses a Sort to perform a number of different functions:
When Oracle performs a sort, all of the matching rows are written to a temporary area (the Sort Area), sorted, and then read back in to the next stage of execution. Small sorts will occur in memory, but a large sort will need to be written out to disk. Whilst the cost of sorting the rows is significant, the IO involved in the read and the write steps can really blow a query out.
If your Explain Plan contains a SORT, consider whether it really needs it.
If your Explain Plan contains two or more sorts, can they be reduced to one or avoided altogether?
Using a MINUS set operator? MINUS sorts both SELECT queries before merging. If the columns you are selecting comprise a unique / primary key, or ROWID, then you may be able to rewrite it as a hash outer join and avoid the sort.
SELECT col1 FROM table_a WHERE col5 > 20 MINUS SELECT col1 FROM table_b WHERE col2 LIKE 'XYZ%' ... becomes ... SELECT a.col1 FROM table_a a, table_b b WHERE a.col5 > 20 AND b.col2 LIKE 'XYZ%' AND a.col1 = b.col1 (+) -- outer join AND b.rowid IS NULL -- return rows that filed the outer join
Using an INTERSECT set operator? If the columns you are selecting comprise a unique / primary key, or ROWID, then you may be able to rewrite it as a hash join and avoid the sort.
SELECT col1 FROM table_a WHERE col5 > 20 INTERSECT SELECT col1 FROM table_b WHERE col2 LIKE 'XYZ%' ... becomes ... SELECT a.col1 FROM table_a a, table_b b WHERE a.col5 > 20 AND b.col2 LIKE 'XYZ%' AND a.col1 = b.col1
Got a DISTINCT or GROUP BY plus an ORDER BY ... DESC? Normally not a problem; Oracle will sort only once. However if the ORDER BY contains a DESC condition for descending order sort, then the ORDER BY will be processed in a separate sort. Consider whether you can do without the DESC clause.
SELECT customer, discount_pct/100, sum(amt)
FROM sales
GROUP BY customer, discount_pct
ORDER BY 1,2
SELECT STATEMENT CHOOSE
SORT ORDER BY
SORT GROUP BY
TABLE ACCESS sales
SELECT customer, discount_pct/100, sum(amt)
FROM sales
GROUP BY customer, discount_pct/100
ORDER BY 1,2
SELECT STATEMENT CHOOSE
SORT GROUP BY
TABLE ACCESS sales
CREATE VIEW sales_summary AS
SELECT customer, dept, sum(sales_amt) as total_sales
FROM sales
GROUP BY customer, dept;
SELECT customer, sum(total_sales)
FROM sales_summary
GROUP BY customer;
SELECT STATEMENT CHOOSE
SORT GROUP BY
VIEW SALES SUMMARY
SORT GROUP BY
TABLE ACCESS SALES
SELECT customer, sum(total_sales)
FROM sales
GROUP BY customer;
SELECT STATEMENT CHOOSE
SORT GROUP BY
TABLE ACCESS SALES