- Don’t forget to tune views. Views are SELECT statements and can be tuned in just the same way as any other type of SLECT statement can be. All tuning applicable to any SQL statement are equally applicable to views.
- Avoid including a
HAVING clause in SELECT statements. The HAVING clause filters selected
rows only after all rows have been fetched. Using a WHERE clause helps
reduce overheads in sorting, summing, etc. HAVING clauses should only be
used when columns with summary operations applied to them are restricted
by the clause.Use:
SELECT city FROM country WHERE city!= ‘Vancouver’ AND city!= ‘Toronto’; GROUP BY city;
Rather than:
SELECT city FROM country GROUP BY city HAVING city!= ‘Vancouver’ AND city!= ‘Toronto’;
- Minimize the number of table lookups (subquery blocks) in
queries, particularly if our statements include subquery SELECTs or
multicolumn UPDATEs.Use:
SELECT emp_name FROM emp WHERE (emp_cat, sal_range) = (SELECT MAX(category), MAX(sal_range) FROM emp_categories) AND emp_dept = 0020;
Rather than:
SELECT emp_name FROM emp WHERE emp_cat=(SELECT MAX(category) FROM emp_categories) AND emp_range = (SELECT MAX(sal_range) FROM emp_categories) AND emp_dept = 0020; - When writing a sub-query (a SELECT statement within the WHERE or HAVING clause of another SQL statement):
- Use a correlated (refers to at least one value from the outer query) sub-query when the return is relatively small and/or other criteria are efficient i.e. if the tables within the sub-query have efficient indexes.
- Use a non-correlated (does not refer to the outer query) sub-query when dealing with large tables from which you expect a large return (many rows) and/or if the tables within the sub-query do not have efficient indexes.
- Ensure that multiple sub-queries are in the most efficient order.
- Remember that rewriting a sub-query as a join can sometimes increase efficiency.
- When doing multiple
table joins consider the benefits/costs for each of EXISTS, IN, and table
joins. Depending on your data one or another may be faster.
Note: IN is usually the slowest.
Note: When most of the filter criteria are in the sub-query IN may be more efficient; when most of the filter criteria are in the parent-query EXISTS may be more efficient.
The following queries return the employee names from each department in department category ‘A’:
SELECT emp_name FROM emp E WHERE EXISTS (SELECT ‘X’ FROM dept WHERE dept_no = E.dept_no AND dept_cat = ‘A’); —————————————————————————————————————————————
SELECT emp_name FROM emp E WHERE dept_no IN (SELECT dept_no FROM dept WHERE dept_no = E.dept_no AND dept_Cat = ‘A’);
————————————————————————————————————————————— - SELECT emp_name FROM dept D, emp E WHERE E.dept_no = D.dept_no AND D.dept_cat = ‘A’;
- Where possible use
EXISTS rather than DISTINCT, to avoid full table scan as DISTINCT operator
causes Oracle to fetch all rows satisfying the table join and then sort
and filter out duplicate values. EXISTS is a faster alternative, because
the Oracle optimizer realizes when the subquery has been satisfied once,
there is no need to proceed further and the next matching row can be
fetched.Use:
SELECT S.id, S.description FROM small_table S WHERE EXISTS (SELECT NULL FROM big_table B WHERE B.id = S.id);
Rather than:
SELECT DISTINCT S.id, S.description FROM small_table S, big_table B
WHERE S.id = B.id; - Where possible use a
non-column expression (putting the column on one side of the operator and
all the other values on the other). Non-column expressions are often
processed earlier thereby speeding the query.Use:
WHERE SALES < 1000/(1 + n);
Rather than:
WHERE SALES + (n * SALES) < 1000; - Where possible use
UNION ALL rather than using UNION. The UNION clause forces all rows
retuned by each portion of the UNION to be sorted and merged and
duplicates to be filtered out before the first row is returned. A UNION
ALL simply returns all rows including duplicates and does not have to
perform any sort, merge or filter. If your tables are mutually
exclusive(include no duplicate records), or you don’t care if duplicates
are returned, the UNION ALL is much more efficient.USE:
SELECT acct_num, balance_amt FROM debit_transactions WHERE tran_date = ’31-DEC-95′ UNION ALL
SELECT acct_num, balance_amt FROM credit_transactions WHERE tran_date = ’31-DE -95′;
Rather than:
SELECT acct_num, balance_amt FROM debit_transactions WHERE tran_date = ’31-DEC-95′ UNION
SELECT acct_num, balance_amt FROM credit_transactions WHERE tran_date = ’31-DE -95′;
More ---> Oracle SQL Tuning Tips - 2
Like the Facebook Page & join Group
https://www.facebook.com/DataStage4you
https://www.facebook.com/groups/DataStage4you
https://twitter.com/datastage4you
For WHATSAPP group , drop a msg to 91-88-00-906098
No comments :
Post a Comment