ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL优化入门(视频笔记20210720)

2021-09-04 12:30:55  阅读:126  来源: 互联网

标签:20210720 语句 入门 --- 索引 SQL 执行 数据


目录

【第一课】

【第二课】

【第三课】

【第四课】接上

【第五课】

【第六课】

【第七课】

【第八课】

【第九课】

【第十课】

【补充】Oracle的数据类型


【第一课】

目标

1. 对Oracle11g有初步了解

2. 能熟练使用SQL语句进行增删改查

3. 熟练使用Data Generator构造性能测试基础数据

4. 能通过AWR手机Oracle性能相关

5. 能通过执行计划诊断SQL语句性能,并初步优化

6. 由Oracle出发掌握不同数据库的学习思路

目录

Oracle简介(简-体系结构)

SQL语句基础

Oracle性能测试大数据制作

Oracle 索引基础

Oracle执行计划

Oracle AWR报告详解

Oracle语句优化与课程总结

1Oracle简介

实例(进程,内存) + 数据库(数据,配置等)= Oracle DB server

2Oracle安装:windows上安装,镜像下载地址:

3Oracle体系结构

1) 体系结构概述(图,手机拍照)

实例

---User process

---Server process, PGA

---Instance: SGA:  Shared Pool(Library Cache, Data Dictionary Cache), Database Buffer Cache, Java Pool(不是必需的), Redo log Buffer, Large Pool(不是必需的), PMON(监控PGA), SMON(监控SGA), DBWR(针对Data),LGWQ(针对log),CKPT, Others…

数据

---Parameter file, Password file, Database(Data files, Control files, Redo Log files), Archived Log files

(1) PGA 

   user1 --- PGA, user2 --- PGA 

   每个用户都有一个与之对应的PGA;

(2) 库高速缓存区 Shared Pool  (包含Library Cache, Data Dictionary Cache)

   存储执行计划

   执行计划类似于旅游攻略

   软解析:有执行计划

   硬解析:没有执行计划

   显然软解析的性能会比硬解析好很多用。

(3) Database buffer cache

   储存数据

   用户访问的数据如果在Database buffer cache,直接返回给用户;

   用户访问的数据如果不在Database buffer cache,DB从硬盘里面把数据读出来放到Database buffer cache,之后再把数据返回给客户端;

  

   指标:缓冲命中率,越高越好(通常要求高于95%)

   逻辑读:数据在Database buffer cache (从缓存读)

   物理读:数据不在Database buffer cache,数据在硬盘上;

4Redo log Buffer日志

         读日志70%+, 写30%-, 把除了读之外的其他操作都记录在Redo log Buffer里,保证数据安全。

一个进程插入数据,会同时写到redo log 和Database buffer cache里。但是提交到系统的时候,先提交日志,然后数据后提交,数据要等到满足一定的条件才能提交:8M,commit。

为什么要先提交日志?出于性能层面的考虑。

针对断电可能带来的数据丢失,可使用UPS提供不间断的供电。

2Oracle 存储结构

-物理存储结构

基础文件:控制文件,联机重做日志文件,数据文件

外部文件:初始化文件,口令文件,归档重做日志文件

-逻辑结构

   逻辑  --------  物理

表空间 -------- 数据文件

区间

Oracle块 ------ 操作系统

【第二课】

(5)SQL 语句执行过程

aread

1) user --- PGA  ---shared pool(有执行计划) --- database buffer chache(有数据的) ---直接返回给客户端;

2) user --- PGA  ---shared pool(没有执行计划) ---生成执行计划 --- database buffer chache(有数据的) ---直接返回给客户端;

3) user --- PGA  ---shared pool(有执行计划) --- database buffer chache(没数据的) ---从硬盘中把数据读出来 --- 放缓存里面 ----直接返回给客户端;

4) user --- PGA  ---shared pool(没有执行计划) ---生成执行计划  --- database buffer chache(没数据的) ---从硬盘中把数据读出来 --- 放缓存里面 ----直接返回给客户端;

  

bwrite

判断数据有没有在缓存里面,如果在,直接操作,如果不在,先把数据读到缓冲中(可能是a中的某一种)

---写日志          ------先把数据写到硬盘上;  (同步的数据操作)

(下面会发生的稍后一些)

---对数据进行操作  ---满足条件后才把数据写到硬盘上去;                                                                        

详情参考: https://www.cnblogs.com/augus007/articles/7999586.html

(写日志是系统自身的行为,日志可用来还原,用来备份。日志远小于数据。)

(读出来的数据可能包含很多数据)

(了解上面这些有什么用?举例: 考虑性能问题,是否加索引等等)

(硬盘的底层原理:不管读多少数据,操作系统底层都是一页一页读,现在的大多数操作系统页大小都是4K)

6)影响性能的点

库高速缓存区的大小及命中率;(空间大,能缓存的执行计划比较多)

Database buffer cache大小及命中率;

     Database buffer cache和库高速缓存区数据过期算法;(80%用默认算法)

     SQL语句;

     索引失效和有没有索引;

     DB读写数据库的性能;

     数据库所在服务器自身配置有问题:CPU、men、IO;

     数据库自身的软件配置;

     数据库所在的操作系统(文件格式、配置(文件句柄数,防火墙是否开启))

     设计对数据库性能的影响:三范式与反三范式,分库分表等;

【第三课】

【PPT】SQL 语句基础

1. SQL语句分类

---数据定义语言DDL D = Definition数据定义语言DDL用于建立,修改,删除数据库中的各种对象

-----表、视图、索引等如: CREATE TABLE/VIEW/INDEX 

---数据操纵语言DML M = Manipulation ,用于改变数据库数据,主要有: 
1) 插入:INSERT    2) 更新:UPDATE    3) 删除:DELETE 4)查询:SELETE

---数据控制语言DCL C = Query , DCL(Data Control Language)是数据库控制语言。

是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。在默认状态下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人员才有权力执行;

2、基本语句—之DDL

CREATE  TABLE –创建新表

ALTER    TABLE –更改表数据

DROP     TABLE –删除表

CREATE   INDEX-创建索引

DROP     INDEX –删除索引

经典面试题:

     drop truncate delete的区别?

3、基本语句-DML

--插入数据  

insert into table1 (id,name) values ('aa','bb');

--更新数据  

update table1 set id = 'bb' where id='cc';

--删除数据  

delete from table1 where id ='cc';

--查询数据  

select * from table1 where id ='cc';

SELECT[ALL|DISTINCT|DISTINCTROW|TOP]

{*|talbe.*|[table.]field1[AS alias1][,[table.]field2[AS alias2][,…]]}

 FROM tableexpression[,…][IN externaldatabase]

[WHERE…] [GROUP BY…] [HAVING…]

 [ORDER BY…]

【执行步骤】:

先从from字句一个表或多个表创建工作表;

将where条件应用于A的工作表,保留满足条件的行;

GroupBy 将B的结果分成多个组;

Having 将条件应用于C组合的条件过滤,只保留符合要求的组;

Order By对结果进行排序;

SELECT语句中的Where条件:

大于、等于、小于或者between and;

like;

In 和exist;

其中:

Like 涉及的性能问题

In和exist涉及的性能问题

A、 in是内外表hash链接;

B、 exist是对外表做loop循环;

SELECT语句中的Where条件:

索引列出现null值,则放弃索引;

使用!=和<>操作符,会放弃使用索引;

对索引列进行运算;

解决方案是 ?

3、SQL别名

表别名或列别名

优点:使用方便,增加易读性;

取名方法:

1)、 字段后面加空格和别名;

2)、as关键字

3)、注意:当别名没有被双引号括起来,其显示结果为大写,如果别名中包含了特殊字符,或想让别名原样显示,用双引号把别名括起来。

4、order by/group by/having子句

where 语句无法聚集函数一起使用, having可以;

where 条件是作用在表上, having是作用在结果上;

select 列名 聚合函数

from 表名

{having  聚合函数 操作符  值}

group  by 配合聚合函数使用,用于其他栏目某个类型的统计(分组);

聚合函数:是对一组值执行计算并返回单一的值的函数,

常与group by一起使用:

AVG;

CONUT;

MAX/MIN;

SUM;

5、常用单行函数

日期(sysdate);

字符(upper,substr、trim);

数值(round,trunc、mod);

转换(to_char、to_date、to_bumber);

通用(nvl,nvl2);

1)、nvl(expl,exp2);

2)、nvl2(expl,exp2,exp3);

6、rownum的使用   

Rownum 是根据sql查询出的结果给每行分配一个逻辑编号;如何查询大于第3条的记录?

7、连接

内连接:join 和 inner join等效;需要on子句;可用where代替,且结果相同

自连接:自己和自己做连接;不需要on子句

         例如:

         Select worker.name,

     Mgr.name

         From worker,mgr

         Where worker.id = mgr.id

外连接

   1)左外连接

   2)右外连接

   3)全外连接

   可省略outer,需要on子句;on 和 where性能问题 ?

【老师笔记】

7SQL语句基础 (重点注意有问题的SQL语句写法)

1)SQL语句执行过程

    先从from字句一个表或多个表创建工作表;

         将where条件应用于A的工作表,保留满足条件的行;

         GroupBy 将B的结果分成多个组;

         Having 将条件应用于C组合的条件过滤,只保留符合要求的组;

         Order By对结果进行排序

2)、insert语句

    insert into student values('04','曾华','男',to_date('1984-9-2','yyyy-mm-dd'),'95033');

         insert into student values('05','匡明','男',to_date('1988-2-4','yyyy-mm-dd'),'95031');

         insert into student values('07','王丽','女',to_date('1990-3-2','yyyy-mm-dd'),'95033');           

         ---这种类型的语句,采用批量插入可以优化,如下:

         insert into student values('04','曾华','男',to_date('1984-9-2','yyyy-mm-dd'),'95033'),('05','匡明','男',to_date('1988-2-4','yyyy-mm-dd'),'95031');

         ---有索引、有外键等约束条件的情况下,把这些约束条件先去掉,数据插入完再加上;

3)、select 语句

select * from

---造成了过多的IO开销 ()

---造成了过多的网络开销

---甚至可能会导致索引失效 (早期版本中,解析sql语句时,看到select*时, 就默认不找索引,直接从内容里遍历,导致效率低,即索引失效。后面的版本中做了优化。 这些不只是mysql还是oracle都是通用的)

优化方法:需要使用几个字段,明确写出来(列出来)就好了

(优化后不一定有效果,影响数据库的点很多,只有当所有点都没问题,有优化时,整体结果才会有明显的优化)

        

【第四课】接上

inexist  (外表和内表的概念):性能低

优化方法:外表数据量大,推荐用in,反之用exist,如果两者数据量差不多的情况下,随便用;

        

like有索引的情况下,like %XXX, 会导致索引失效;

优化1:

select id,name from a where like abc% --- 可能的优化方式 (基于实际的业务)

优化2:  

使用函数索引的方式来解决问题;(如何使用函数索引)

                                    

null在含有null的列上建索引,会导致索引失效,进行性能低;

优化1:

建表的时候,SQL语句指定不能为空is not null;

优化2:

建表的时候(如果是增加索引的时候,检查是否有null,有就给默认值),null给默认值;

索引列有函数、运算(=, >=)

优化:

尽量避免,甚至改写SQL语句;

select * from a where id -1 =5000; //表示在索引页上有运算,影响性能

--->SQL 改写

select * from a where id=5000+1;

select * from a where id=5001;

        

order by /group by

--问题都是性能低

优化1:用索引来优化;

优化2:调整SGA的内存参数大小;

优化3:从业务角度考虑当前的实现方式好不好;(比如开发写出来的语句,建表结构不好很烂)

作为性能测试工程师,要了解业务,了解开发如何实现业务,了解数据库,了解开发建表是否合理。

4)开发的常见问题

表设计不合理

数据库设计三范式使用不当,造成性能问题----目前可先放放,未来个人进阶

另外一种具体的表在字段选择和字段类型选择上不合理。

举例1:  

create table p_test(

         int id,

         name char(40),

         descriptrion blob

);

        

问题点:

可能:主键到底需要不需要?                               

肯定:

char ---浪费空间--- 有问题 --- 怎么优化用:varchar

blob ---浪费空间--- 有问题 --- 怎么优化用:varchar(255)

举例2:               

create table p_test(

         int id,

         createTime varchar(40),

         fromIpAddress varchar(20)

);      

问题点:createTime、fromIpAddress可用用简单数据类型来搞定;

总结:字段能用简单的就用简单的类型,字段长度能小就尽可能小;

  

https://www.cnblogs.com/buxingzhelyd/p/8984173.htmlOracle的数据类型,重要!

5)、表之间的各种连接关系

真实世界:1:n,n:1等关系   ---开发抽象实现的

SQL层面:各种连接(内连接、外连接等);----对真实世界中各关系的实现

DB内部实现:各种算法(迭代循环、归并排序、哈希连接)---我们测试干预不了的,我们能做的事情是,SQL改写或者调整等来影响DB内部的实现。

  

(到底能不能做,一定要基于业务)

(数据设计不合理,就需要分表,表多了也不优。一旦连接的表到了4张之后,或者一个表加了6个以上的索引的时候,就需要考虑表和数据的设计是不是合理的了)

【第课】

1、缓存读写策略

   当前缓存使用主流有两种策略:

   1)、旁路策略

   2)、写穿、写穿策略

   https://www.cnblogs.com/llzhang123/p/9037346.html

2、数据制作方法

   1)、为什么要制作数据: 为了更加真实的模拟现实情况。模拟真实的用户环境,尤其涉及SQL中DDM操作时。

   2)、都有哪些方法:

         用代码生成:  API代码(本质是有界面或没界面的客户端),SQL代码(存储过程)

         用工具生成:  UI自动化工具生成数据,性能测试工具生成(Data Generator);

         第三方库导入:生产数据脱敏后直接用(让运维导数据时注意提醒脱敏)

         推荐:采用性能测试工具来生成。

  

   3)、如何知道我们要制作多少数据:

                   根据性能测试需求分析出来的结果决定我们要生成多少数据。(根据系统的具体情况来定)

                   原则:宁多勿少(但是如果多过份了,也是我们不能接受的)

  

   4)、业界数据制作发展到了那几个阶段(了解)

                   业界目前发展经过了三代

                   第一代:直接代用上述方法生成测试数据;

                   第二代:对上述代码做了封装,将其做到了平台化;

                   第三代:平台化后的数据生成支持跨平台,支持自动化;

【第课】

   5)、性能测试到底需要制作什么数据

                   基础数据(比如登陆用的用户名、密码)、业务数据(订单号、支付信息)

                   铺垫数据(比如测登陆时提前准备一些用户名账号):

                   消耗数据(每测一次就消耗掉一个数据,订单号,支付数据之类的):

性能测试是对多个接口做测试.接口测试就是单个接口测试.

很多性能测试问题没测出来的原因:环境和线上真实的环境有差异,数据量不够.    

   6)、数据制作

   先生成所需要的表

         create table datatest(

         deptno number(6),

         dname  varchar2(20),

         loc varchar2(20)

         );

根据业务需要选择合适的数据生成规则,生成数据。

        

客户端: PL SQL developer -> 工具-> 数据生成器

建表建数据过程:

SQL建表语句,运行,生成表。

         针对每个表字段,选择相应的生成数据的规则(变量,范围, 函数等)。

         左下角三个按钮,先预览生成的数据,再运行最后一个按钮将这些数据插入表格。

         查询表格,看看是否已成功插入数据。

         PS:

         数据制作的难点:在于分析表和表之间的关联关系(和开发聊、自己看代码、慢慢猜);

         如果需要生成的数据比较多,那就分批插入就好了。

        

         课堂练习

create table stu33(

sid number(10), //持续递增,Sequence(1,1),第一个参数表示从1开始,第二个参数表示间隔

sname varchar(30) , //随便组合一下,比如就用FirstName

ssex  varchar(20) , //man或women, 用枚举, List(‘men’,’women’,)

sbirthday DATE,     //to_date(‘2003/07/11’,‘yyyy/mm/dd’)会生成乱码 . 试试用随机数Random(‘1980/01/01’, ‘2000/12/21’)

stel number(11),   //第一位固定为1, List(‘1’,)+[0(10..10)]

sclass varchar(20)   //List(‘1年级’, ‘2年级’,)

 );使用Data Generator生成1000条数据 //在Number of record: 10000..10000

补充:不同表格中字段有关联的时候怎么处理?用这种生成数据的工具不好处理,用存储过程来处理。

【第课】

上节课练习讲解:

1)日期出不来怎么办?方法不限,能拼成想要的数据就行。

2) 有的项的值是空的,是因为比如List(‘1年级’, ‘2年级’,)最后多了一个逗号, 把逗号去掉就行

3)数据量很大的时候,要分批插入。可以通过Optionsl里控制一下节奏,有两个可以设置:延迟,每个多少时间提交一次。

4)插入之后要关注是否插入成功。不成功的原因和处理方式:先看有没有权限?确保有权限。然后看SQL是否成功,可以单独执行SQL语句看看。

3、索引基础

   1)、什么是索引

为了提高查询效率的一种数据结构(可以是一棵树,也可以是一张表), 类似于字典。

  

   2)、索引的原理?

   没有索引数据的查找是,全表扫描;

   有了索引之后,数据查找时,先在索引中查找,如果索引中能找到,通过索引给出的线索到数据库中查询所需的数据;

   如果索引里面也没找到,那就进行全表扫描(通常是索引失效引起的)

  

   3)、索引分类

    --B树索引:从数据结构的角度来说的(唯一索引/主键索引 ===>非唯一索引),可以是单列索引,也可以是复合索引;

         --位图索引:从数据结构的角度来说的

         --单列索引和复合索引:从索引所包含的列来说的

        

         适用场景:

B树索引使用列基础非常大,且离散度的字段建立索引;(列基数大指的是在这一列上拥有的数据量大,而且不重复)

         位图索引适用于列基础小,且离散度不高的字段建立索引;(列基数上重复性很高,比如男和女,就是离散度不高的字段)

                              

         比如:四川7000W要建立索引,使用B+树这种;

         而如果是在四川7000W人的性别字段上建立索引,位图索引会比较适合。

        

         alter table table_name add index index_name(id); ---(B+数的)单列索引

         alter table table_name add index index_name(id1,id2); ---(B+数的)复合索引

 4)、索引使用原则

         --对表而言,是不是大表,小表没有必要建立索引,大表才考虑建立索引;---大表小表都是相对的,没有绝对的标准,也不能单纯从数据量的情况来看,一切以性能测试结果说明为准;

         --建立索引的索引的时候,要在常用的字段上建立索引;

         --B树索引使用列基础非常大,且离散度的字段建立索引;

    --位图索引适用于列基础小,且离散度不高的字段建立索引;

         --索引在建立过程中,要适当考虑索引失效的情况;

        

         PS:如果你的表你建立索引在> 4个,这个要你要考虑一下的表设计是不是合理的;因为过多的索引反而会影响到你的查询速度。     

         key 和索引有关系也有区别。

         PS:不是有了索引之后,数据库查询的时候,就一定会走索引。结构会有自己的算法,计算之后会选择最优的方法去搜索。       

不管用什么方式,一定要有铺垫数据。

【第课】

   5)、索引的底层算法 (很重要,很多公司的面试题)

         a、为什么采用B+树作为索引结构;

线性查找 --- 查找效率不高

二分查找 --- 随着数据量的增大,复杂度还是很大(并且隐含的排序这个操作的开销会很大)

二叉树查找 -- 极端情况,二叉树会变成线性表,随着数据量的增大,复杂度还是很大

红黑树  ---  极端情况下,树的高度还是很高,树的高度越高,IO开销越大;(红黑树动画在线演示PS :https://rbtree.phpisfuture.com/)

B树--- 通过引入度(一个节点可以存储多少数据,我们称为度:4k)

B+树---mysql只有B+树,oracle有多种。

         b、为什么采用位图作为索引结构

因为在某些字段离散度不高的情况,如果采用B+树这种数据结构,效率不高。

                           

   6)、如何利用索引优化性能问题

                   首先是要值得优化;

                   需要采用索引来进行优化;

                   采用索引来优化;

         对数据库而已,我们的要求是:能不做就不做,能少做就少做。

         不管有多大的数据,都是需要铺垫数据的。铺垫数据多少,要看系统要使用多长时间?这个时间后要如果进行归档,数据都被清掉,一切又从零开始。铺垫数据可以是消耗数据,也可以是不消耗的数据。铺垫数据的目的在于让我们系统查询起来时跟真实情况一样。

补【PPT】

4、创建/删除索引

CREATE [UNIQUE] | [BITMAP] INDEX index_name  --unique表示唯一索引

     ON table_name([column1 [ASC|DESC],column2    --bitmap,创建位图索引

[ASC|DESC],…] | [express])

      [TABLESPACE tablespace_name]

drop index index_name –删除索引

5、索引失效示例

典型:

通配符在搜索词首出现时,oracle不能使用索引;

不要在索引列上使用not,可以采用<、>代替;

索引上使用空值比较将停止使用索引;

例如:

--name上创建索引;

create index index_name on student(‘sname');

--下面的方式oracle不适用name索引

select * from student where name like '%wish%';

--如果通配符出现在字符串的其他位置时,优化器能够利用索引;如下:

select * from student where name like 'wish%';

6. 索引使用总结

(1)小表:不建立索引

(2)大表:查询时走了全表扫描

---没有索引,则建立索引:

列基数大建立B树索引

列基数小建立位图索引

经常查询的列简历索引,且放到最前面

---检查索引失效:

唯一索引引起非唯一索引失效

组合索引中,第一列的值没有被使用到

索引简历的列中包含null值

like参与的模糊查询中,出现了 like %XXX%的情况, 可改成instr(字段名, ‘XXX’)

索引列上进行了数学运算

索引列上使用了Not, 可以采用<,>代替

索引列上使用了函数

(3)索引使用过程中的一些误区

索引并不是越多越好

并不是有了索引查询速度就一定快

并不是有了索引就能完美解决数据库性能问题

【第课】

1、执行计划

   执行计划并不是真实的在执行SQL语句,而是在模拟SQL语句执行;

(SQL语句执行时,Oracle根据自身算法计算出来的执行路径,类似于我们自驾去西藏时做的自助游攻略)

   所以:执行计划中看到的各种开销只有参考意义,没有决定意义。

  

   执行计划的意义:SQL优化(调优)的第一步。

   使用执行计划的前提:一定的数据量和硬件环境。  

   执行计划要看的点:

   1)cost值大小 --- 一般越小越好;

   2)SQL语句的执行顺序:向右缩进最多的优先执行,向右缩进相同的从上往下执行;

---缩进最多的最先执行(缩进相同时,最上面的最先执行)

---同一级如果某个动作没有子ID,就最先执行

---同一级的动作执行时,遵循最上最右先执行的原则

看懂执行计划(嵌套循环连接,排序合并连接,哈希连接, 图略,手机拍照)

   3)表的访问方式

Index UNIUQE SCAN:索引唯一扫描

Index Range Scan:索引范围扫描;

Index full scan : 索引全扫描(覆盖索引的情况下)

Index fast full scan:索引快速扫描

Index skip scan:索引跳跃扫描(复合索引第一列没有出现在查询条件中,oracle有mysql无)

 4)表的连接方式

迭代循环:

归并排序:

哈希连接:

                  

PS:

在做对比测试中,除了保证数据量相同,硬件环境相同外,还要清掉库高速缓存区和database buffer cache。 屏蔽这两个点的影响:

如何清除命令:

alter system flush shared_pool;

alter system flush buffer_cache;

5)PL/SQL执行计划进行SQL调优步骤

---查看cost, 获得总体印象

---分析执行步骤

---分析表的访问方式

---分析表连接方式和连接顺序

---项目组求助

6)使用执行计划优化SQL语句

例1:

create   table   datatest2

         ( deptno   NUMBER(6),

         dname    VARCHAR2(20),

         loc      VARCHAR2(20));

         使用 Data Generator生成20000条数据。

在执行计划中输入:

select   *  from  datatest2 where deptno =15000 ;观察执行计划,重点cost值;

创建索引

create  index  dindex on datatest2(deptno)

在执行计划中输入:

select   *  from  datatest2 where deptno =15000 ;观察执行计划,重点cost值;

在执行计划中输入:

select   *  from  datatest2 where dname like ‘%a%’ ;  观察执行计划,重点cost值;

在执行计划中输入:

select   *  from  datatest2 where dname like ‘a%’ ;    观察执行计划,重点cost值;

7)关于执行计划

(1)、执行计划,只是SQL运行前可能的执行方式,实际运行时可能因为软硬件环境的不同,有所改变,而且cost高的执行计划,不一定在实际运行起来,速度就一定差。

(2)、对于表的连接顺序,多数情况下使用的是嵌套循环,尤其是在索引可用性好的情况下,使用嵌套循环式最好的;当ORACLE发现需要访问的数据表较大,索引的成本较高或者没有合适的索引可用时,会考虑使用哈希连接,以提高效率。排序合并连接的性能最差,但在存在排序需求,或者存在非等值连接无法使用哈希连接的情况下,排序合并的效率,也可能比哈希连接或嵌套循环要好

(自己总结)

写SQL语句,选择,右键,Explian Plan,弹出一个框,就是执行计划内容(Tree, HTML,Test, XML)。

SQL语句执行计划的多个注意点:

1)向右缩进越多的先执行。缩进情况相同的,从上往下执行。

2)注意看各个列的意思(Description, owner, object name, cost, cardinality, bytes…):

--cost越小说明执行计划越好,cost的单位是单位块,大小是相对意义的,只是优化的一个参考值而已(在一定的数据量,一定的硬件环境中)。执行计划得出的cost只是一个估算值。执行计划只是利用系统中的各种数值和算法得出。cost计算时,很多PC的事情开销,是没算进来的, 在数据库之外。

--对数据库来说,什么是执行计划:

硬盘 à 内存 à PC à 人:人给指令给PC, PC要求内存加工数据,数据是从硬盘读取的,内存加工完数据后返回给PC。 这个过程中,硬盘到PC之间的这段操作,就是执行计划。

操作:

在PLSQL中生成数据,插入数据。

然后SQL语句(select * from datatest)右键执行计划,看cost值。

cost值不太好,这里有两个坑:

1)加了索引也不一定好,因为不一定有索引就一定要用索引,索引不一定是最快的。

2)要把告诉缓存区和database buffer cache的数据清掉。

有没有改善的空间?

--在表中加个索引,

alter table datatest add index idx_id(DEPTNO)

create index idx_id on datatest(DEPTNO)

然后再执行上面相同的SQL语句(select * from datatest),看执行计划的结果。此时看到还是全表扫描,为啥不走索引?因为索引加在deptno字段,没使用到。

改SQL语句: select deptno from datatest where deptno=1000;

此时看执行计划,就是走了索引,cost值小了,即得到优化。

然后再试试去掉索引:

drop index idx_id;

再执行计划,看cost: 又变成2(没有得到优化).

然后再清掉:

alter system flush shared_pool;

alter system flush buffer_cache;

再执行计划,看cost: 还是2(没有得到优化).

然后再加索引

再清掉shared_pool,buffer_cache

再执行计划,看cost: 2(得到优化).

补充:

SQL语句中的大于小于会导致索引失效。如果SQL里没有大于小于但还是走全表扫描,不走索引,是因为执行计划自己评估下来后得出走全表扫描比较好。

小结:

怎样利用执行计划来对SQL语句进行优化。先看cost 然后修改SQL(加索引啊,清缓存啊…),然后执行计划,再看cost是否有优化。有的话说明改好了一些,没有的话,继续改。

【第课】

1. Oracle AWR 报告详解(PPT),本质就是一个监控

先要生成AWR报告,用PLsql无法生成。用别的(doc命令)。

1)简介

AWR (Automatic Workload Repository) 是自动负载信息库的英文缩写,AWR报告是Oracle 10g以后版本提供的一种性能收集和分析工具,是Oracle数据库的一个体检报告。

通过它可以对数据库运行状态进行监控,发现数据库使用过程中可能存在的性能瓶颈。

2SQL语句执行过程

3)生成AWR报告

Dos 下输入:

1、sqlplus  system/oracle  as  sysdba;

2、SQL> @?/rdbms/admin/awrrpt.sql;

3、输入 report_type 的值:  html             报告格式,还可以是text;

4、输入 num_days 的值:  3                     假设是3天;

5、输入 begin_snap 的值:  192                   假设是192

6、输入End   Snapshot Id specified: 194      假设是194

7、输入 report_name 的值:  20171225_awr.html   报告的名字,可自定义;

8、输入exit

9、到指定路径(首次打开dos窗口的路径),找到报告并打开;

4AWR报告中的关键指标

---平台信息: 主机信息,内存信息,主机系统

---Oracle版本信息

---ElapsedTime/DB time/Average Active Session

---Logical Read / Logical Write & Physical Read/Physical Write

---Parse: soft Parse > 95%, hard Parse

---Instance Efficiency Percentages: Buffer Hit> 95%, Latch Hit > 95%,

Buffer Hit低的原因:Buffer设置小,没有绑定变量,SQL语句有问题

---SQL Statistics:

SQL ordered by Elapsed Time (关注高频耗时)

SQL ordered by CPU Time (关注高频耗时)

Complete List of SQL Text

(2)如何看报告? 先看整体再看详细。

关注: DB时间,软硬解析命中率,高速缓存/buffer cache命中率,逻辑数越大越好,物理数越小越好,

1)DB time不包括Oracle后台进程消耗的时间。如果DB time远小于Elapsed时间(和数据库相关的总的时间),说明数据库比较空闲。 db time = cpu time + wait time(不包括空闲等待)(非后台进程)。

说白了DB time就是记录的服务器花在数据库运算(非后台进程)和等待(非空闲等待)上的时间。

DB time = cpu time + all of nonidle wait event time

在79分钟(Elapsed)里(其间收集了3次快照数据),数据库耗时11分钟(DB time),RDA数据中显示系统有8个逻辑cpu(4个物理CPU),平均每个CPU耗时1.4分钟,CPU利用率只有大约2%(1.4/79). 说明系统压力很小。

即:要考虑DB time和核数的关系。

2)物理读和物理写(有对应的单位):

物理读越小越好,逻辑读是越大越好。

3)硬解析和软解析

不知道一个硬解析的值好还是不好,接下来看buffer cache命中率还行,锁的命中率还行,但是软解析命中率不太好,分析一下什么原因。

4)往下拉,看报告主体。

SQL语句的状态 (消耗比较多的SQL语句。。。)

IO的状态

Buffer cache的细节信息

关注哪些点再强调一些:高频(Executions) 耗时(Elapsed time)

SQL id (如果数据库被攻击,这一列会看到五花八门的ID?IP?)

SQL Module (连接的一些外部的客户端?)

SQL Text (SQL语句的描述)

怀疑某条SQL语句有问题,如何处理?

把该SQL语句放到PL SQL 中,看执行计划,开销,然后修修补补

实例:https://www.cnblogs.com/bingjava/p/5255760.html (具体看看,学习。真实案例!)

快照可以手动生成。

2. SQL语句优化原则

---不要让Oracle做得太多

避免使用*

exists和in关系(内表数据量大时用exists, 反之用in)

---合理使用索引

---减少访问次数

3. 本课程内容总结

(1)数据生成: Data Generator

(2)执行测试: 性能测试工具(UI/数据库测试工具)

(3)问题SQL:AWR找到有问题的SQL语句

(4)优化SQL: 执行计划优化SQL语句

4. 关于SQL性能优化

---依据: SQL的执行计划,性能报告

---方法:充分利用索引,尽量减少I/0,  尽量的缩小数据(业务上支持)

---如何判断:并不是性能越高越好,是在合理的成本下,满足业务应用就好。脱离业务需求谈技术都在耍流氓。性能测试中,被测系统是个整体,除了SQL语句,我们还可以从如下方面发力:

业务优化: 最显著,成本太高

程序优化: 收益高,时间长

资源优化: 省事不省心,缓解

配置优化: 提高利用率,最简单

推荐书籍: 《高性能MySQL》第三版

学习方法:

学技术,多动手多总结

记不住的原因:用的少,没有体系化

自学能力,自律。真正牛逼的技术,更多的是自己琢磨出来的。

要有替换性想法,任何人任何书,全听不行,全不听也不行。

能解决问题的就可以,其他的当做理论。

【补充】Oracle的数据类型


常用的数据库字段类型如下:


字段类型    中文说明  限制条件    其它说明
CHAR         固定长度字符串 最大长度2000 bytes
VARCHAR2        可变长度的字符串 最大长度4000 bytes 可做索引的最大长度749
NCHAR      根据字符集而定的固定长度字符串 最大长度2000 bytes
NVARCHAR2       根据字符集而定的可变长度字符串 最大长度4000 bytes
DATE          日期(日-月-年) DD-MM-YY(HH-MI-SS) 经过严格测试,无千虫问题
LONG          超长字符串 最大长度2G(231-1) 足够存储大部头著作
RAW          固定长度的二进制数据 最大长度2000 bytes 可存放多媒体图象声音等
LONG         RAW 可变长度的二进制数据 最大长度2G 同上
BLOB         二进制数据 最大长度4G
CLOB         字符数据 最大长度4G
NCLOB       根据字符集而定的字符数据 最大长度4G
BFILE          存放在数据库外的二进制数据 最大长度4G
ROWID      数据表中记录的唯一行号 10 bytes ********.****.****格式,*为0或1
NROWID   二进制数据表中记录的唯一行号 最大长度4000 bytes
NUMBER(P,S)    数字类型 P为总位数,S为小数位数
DECIMAL(P,S)   数字类型 P为总位数,S为小数位数
INTEGER    整数类型 小的整数
FLOAT       浮点数类型 NUMBER(38),双精度
REAL         实数类型 NUMBER(63),精度更高

数据类型        参数          描述
char(n)    

n=1 to 2000字节 定长字符串,n字节长,如果不指定长度,缺省为1个字节长(一个汉字为2字节)

varchar2(n)

n=1 to 4000字节 可变长的字符串,具体定义时指明最大长度n,这种数据类型可以放数字、字母以及ASCII码字符集(或者EBCDIC等数据库系统接受的字符集标准)中的所有符号。

如果数据长度没有达到最大值n,Oracle 8i会根据数据大小自动调节字段长度,如果你的数据前后有空格,Oracle 8i会自动将其删去。VARCHAR2是最常用的数据类型。可做索引的最大长度3209。

number(m,n)

m=1 to 38
n=-84 to 127 可变长的数值列,允许0、正值及负值,m是所有有效数字的位数,n是小数点以后的位数。
如:number(5,2),则这个字段的最大值是99,999,如果数值超出了位数限制就会被截取多余的位数。
如:number(5,2),但在一行数据中的这个字段输入575.316,则真正保存到字段中的数值是575.32。
如:number(3,0),输入575.316,真正保存的数据是575。

date 

无 从公元前4712年1月1日到公元4712年12月31日的所有合法日期,Oracle 8i其实在内部是按7个字节来保存日期数据,在定义中还包括小时、分、秒。
缺省格式为DD-MON-YY,如07-11月-00 表示2000年11月7日。

long 

无 可变长字符列,最大长度限制是2GB,用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型。long是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。

raw(n)

n=1 to 2000 可变长二进制数据,在具体定义字段的时候必须指明最大长度n,Oracle 8i用这种格式来保存较小的图形文件或带格式的文本文件,如Miceosoft Word文档。
raw是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。

long raw

无 可变长二进制数据,最大长度是2GB。Oracle 8i用这种格式来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件。
在同一张表中不能同时有long类型和long raw类型,long raw也是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。

blob /clob /nclob 

无 三种大型对象(LOB),用来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件,最大长度是4GB。
LOB有几种类型,取决于你使用的字节的类型,Oracle 8i实实在在地将这些数据存储在数据库内部保存。
可以执行读取、存储、写入等特殊操作。

bfile 

无 在数据库外部保存的大型二进制对象文件,最大长度是4GB。
这种外部的LOB类型,通过数据库记录变化情况,但是数据的具体保存是在数据库外部进行的。
Oracle 8i可以读取、查询BFILE,但是不能写入。
大小由操作系统决定。

标签:20210720,语句,入门,---,索引,SQL,执行,数据
来源: https://blog.csdn.net/sulia1234567890/article/details/120097983

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有