sql优化(针对oracle12C)

1.想要检索一行或者几行时,用where子句过滤行

select * from customer:

select * from customer where customer_id in (1,2); 将要检索的行限制在需要的行中

2.使用表连接而不是多个查询

select name,product_type_id from products where product_id=1;

select name from product_types where product_type_id = 1;

select p.name,pt.name from products p,product_types pt where p.product_type_id = pt.product_type_id and p.product_id=1;


3.执行连接时使用完全限定的列引用

select p.name,pt.name,description,price from products p,product_types pt where p.product_type_id =pt.product_type_id and p.product_id=1;

select p.name,pt.name,p.description,p.price from products p,product_types pt where p.product_type_id =pt.product_type_id and p.product_id=1;

省的数据库再去两个表搜了,非智能,只能人为的干预

4.使用case表达式而不是多个查询

需要对表的相同行执行许多次计算

select count(*) from products where price <13;

select count(*) from products where price between 13 and 15;

select count(*) from products where price > 15;

select 

     count(case when price <13 then 1 else null end) low,

     count(case when price between 13 and 15 then 1 else null end)med,

     count(case when price >15 then 1 else null end) high from products;

case 表达式中可以使用重叠的范围和不同的函数


5.添加表索引

5.1 何时创建B-树索引,当单个查询检索的行数小于等于表总行数的10%时,建立B-树索引。

oracle数据库会自动为表的主键和包含在唯一约束中的列创建B-树索引

当执行分层查询(包含connect by的查询时)应该为start with和connect by 子句引用的列添加B-树索引

5.2何时创建位图索引

包含小范围值,在where子句中频繁出现的列加位图索引,此索引用于数据仓库,读的多,改的少(并发修改很少)


6.使用where而不是having

where过滤行,having子句用于过滤行组,行被分组后having才可以上场

select product_type_id ,avg(price) from products group by product_type_id having product_type_id in (1,2);  反例

select product_type_id ,avg(price) from products where   product_type_id in (1,2)     group by product_type_id ; 正例


7.使用union all 而不是union

union all两个表的所有行,包括重复行

union是所有不重复的行(需要删除重复的行,费时间)

select product_id,product_type_id ,name from products union select prd_id,prd_type_id,name from more_products;去了重复

select product_id,product_type_id ,name from products union  all select prd_id,prd_type_id,name from more_products;会重复

个人觉得视使用场景而定

8.使用exists而不是in

in用于检索一个值是否包含在列表中,查的是实际的值

exists用于检查子查询返回行的存在性

select product_id,name from products where product_id in (select product_id from purchases);

select product_id,name from products outer where exists (select product_id from purchases inner where inner.product_id=outer.product_id);

9.使用exists而不是distinct

distinct是去重,在排除重复行之前要对检索到的行排序

select distinct pr.product_id,pr.name from products pr ,purchases pu where pr.product_id=pu.product_id;

select product_id,name from products outer where exists (select 1 from purchases inner where inner.product.product_id=outer.product_id);


10.sql的缓存

先查缓存,但是sql语句必须是一模一样才可以,字母大小写,空格,字符等必须是一模一样才可以,缓存的命中率

绑定变量,也可以命中缓存

begin

:v_product_id:=1;

end;

select * from products where product_id = :v_product_id;



begin

:v_product_id:=2;

end;

select * from products where product_id = :v_product_id;

这样的两个是同一个sql语句,通过变量的赋值来命中缓存,提高性能

你可能感兴趣的:(sql优化(针对oracle12C))