最近各种加班,忙于指标项目的测试,终于有时间闲下来看书了。
这次的学习笔记是第八章,调优技巧,闲话不多说,开记!
一、使用UNION代替OR
当SQL语句中同时有or和子查询,这种情况爱查询无法展开(unnest),只能走FILTER。这时将or改为union
例:
SELECT * FROM
FROM T1
WHERE OWERN = 'SCOTT'
OR OBJECT_ID IN
(SELECT OBJECT_ID FROM T2);
/* 改写为 */
SELECT * FROM T1 WHERE OWER= 'SCOTT'
UNION
SELECT * FROM T1 WHERE OBJECT_ID IN (SELECT OBJECT_ID FROM T2);
此时需要将T2.OBJECT_ID建立索引即可。
二:分页语句优化
1、首先,应该明确分页语句的SQL框架:
SELECT *
FROM (SELECT *
FROM (SELECT A.*, ROWNUM RN
FROM (需要分页的SQL) A )
WHERE ROWNUM <= 10)
WHERE RN >= 1
先利用ROWNUM进行编号,如果需求1-10数据,先过滤掉大量数据, 取小于等于10的数据,这时只扫描10行就停止了,然后再取大于等于1的。
其次,如果需要分页的SQL中有排序,我们要利用索引已经排序的特性,将order by的列包含在索引中,同事也要利用rownum的COUNT STOPKEY特性来优化SQL。如果没有排序,直接利用rownum优化。
如果分页语句中出现了SORT ORDER BY,意味着分页语句中没有利用到索引已经排序的特性,这时候需要创建正确的索引。
那么创建索引的时候,要优先将等值过滤和排序列组合在一起,然后再将非等值过滤列放后面。排序列的索引,正序倒序创建要和SQL中保持一致,前后顺序也要保持一致。
2、以上都是针对非分区表,那么如果要是分区表又该如何优化呢?
如果是没有筛选条件(个人理解不跨区应该也行),分区恰好是范围分区,由于范围分区每个分区的数据都是递增的,这时候的索引创建为local索引即可。但是如果分区是LIST分区或者HASH分区,这时候