Oracle-数据库优化

执行计划

数据库优化相关

在执行计划里面需要看什么内容

  1. 查看一个sql语句前后查询表格的顺序和逻辑

  2. 查看每一次对表的查询是否使用了分区和索引或者是全表查询

  3. 查看系统的cost资源消耗

  4. 每次运行查询结果的行数

  5. 每次查询结果得出的字节数大小

  6. CPU计算的资源消耗

  7. 硬盘读写的资源消耗

  8. 每个句子运行的毫秒数时间

通过执行计划看到的表连接的内部逻辑

hash哈希连接

列和列的等值连接,通过某个列和某个列相等来进行表连接的时候,使用的是hash连接

当两表的数据量相差比较大的时候,即使一个表有索引,也是哈希连接

select * from emp a join dept b on a.deptno = b.deptno;

select * from emp a join dept b on a.job='CLERK' and a.deptno=b.deptno;

NL嵌套连接

列和列的不等值连接,通过两个列的不相等来进行表连接

连接的两张表

​ 当数据量的区别不是很大的时候,连接的列有索引的情况下,这个时候列和列的等值连接是NL嵌套连接;

​ 如果当两表的数据量相差比较大的时候,强制让大表先运行,一个表有索引的时候,此时是NL嵌套连接

select * from emp a join dept b on a.deptno != b.deptno;

select * from emp a join dept b on a.job='CLERK' and a.deptno!=b.deptno;

select * from emp_i a join dept_i b on a.deptno=b.deptno

merge join排序归并

列进行具体值的查询

select * from emp a join dept b on b.deptno=20;

select * from emp a join dept b on a.ename like 'S%';

强行更改表格查询的内部逻辑

优化器

使用优化器来更改: hints优化器 /*+ 优化器的内容 */ 放在select后面,放在列的前面

更改表连接的逻辑:

  1. 强制使用hash连接 /*+ use_hash(a b) */

  2. 强制使用nl连接 /*+ use_nl(a b) */

  3. 强制使用merge连接 /*+ use_merge(a b) */

  4. 强制改变表格读取的顺序 /*+ leading(a b) */

    a 小表:驱动表 b 大表:匹配表

  5. **多线程:/*+ parallel(线程数量)*/

    select /*+ parallel(8) */* from emp_more a join dept_i b on a.deptno=b.deptno;
    
  6. 选择表格扫描的方式:

    /*+ full(表名) */
    
  7. 强制更改索引

    /*+ index(表名  索引名) */
    
  8. 在数据插入的时候,让数据默认都是直接追加到表格的末尾

    insert /*+ append */ into dept_i values(50,'BIGDATA','SHENZHEN');
    

怎么去做数据库优化的?

  1. 首先查看表格的数据量,数据量如果超过了2000W就一定要去给表格设置分区

  2. 表格中的索引是否合理(表格一定要有主键,索引的数量(大表索引不能超过5个,小表索引不能超过列数量的15%))

  3. sql语句里面有没有导致索引失效的情况

  4. 如果要做联合查询,先筛选数据,然后对筛选后的结果做表连接

  5. 如果表的数据量特别大,然后又需要做表连接,就需要将筛选结果存入到临时表,然后用临时表进行表连接

  6. where查询的顺序,数据筛选量大的放在右边,筛选量小的放在左边

  7. 尽量先用where筛选然后再分组,having只对聚合结果筛选

  8. 尽量不要用select * from 表

  9. 尽量使用decode()去替代case when,函数计算效率更高

  10. 使用union all替代or,union all是并行

  11. 使用group by 替代distinct,分组比以行为单位筛选更快

  12. 使用大写的sql替代小写的sql,数据库本来就是要转换成大写再运行的

  13. 尽量少使用union minus intersect这三种集合运算,这三种集合会多一步sort unique的排序操作

  14. 使用exists()函数去替代in 包含语句

exists() 语法

select * from 原表 a where exists(select 1 from 原表 b where 查询条件);

--查询和SMITH岗位相同的其他员工信息

select * from emp where job in (select job from emp where ename='SMITH') and ename!='SMITH';

--结果上下是一样的,exists函数计算效率更高,用1来select是因为exists不关注查询的结果,只关心有没有数据,所以1可以尽可能减少需要反馈的信息

select * from emp a where exists(select 1 from emp b where b.ename='SMITH' and a.job=b.job) and ename!='SMITH';
posted @ 2020-10-07 20:02  Hedger_Lee  阅读(207)  评论(0编辑  收藏  举报