学习总结

sql的执行过程及工作中常见的问题汇总

当客户端向数据库发起一条select查询语句,首先到达数据库监听,数据库监听会为该客户端和数据库服务器之间建立起一个独自的连接,这样客户端就可以直接和数据库通信了。

 

监听常见的问题:dns解析有问题:nslookup命令查看域名

                             remote_listener参数设置错误

                             local_listener参数设置错误

                             网络层面问题,客户端本地telnet端口,测试

当客户端和数据库建立一条通信以后,数据库首先验证客户端数据库登录用户和密码。

 

密码登录问题:11g新特性密码延迟验证

                          数据库的现象是大量的library cahce lock等待事件,v$session中用户为空,

 awr时间模型统计也能看到用户登录失败的信息排在前面(没有实际的awr,下图仅为表示在哪里)

clipboard.png

客户端成功登录后,开始执行select查询语句,sql语句传输到数据库后,数据库会将sql转化为对应的ascii值,然后按照hash算法计算出该sql对应的hash值。

share poollibrary cache中查找sql对应的hash值是否存在,如果不存在则进行以下步骤。

硬解析:

1)语法检查(sql是否写错,from写成form

2)语义检查(查询的字段是否都存在,表是否存在)

3)获取对象相关的解析锁(相关对象处:library cache:mutex x

4)权限检查(相关表和视图是否又对应的权限)

5)生成执行计划

执行计划:

对象的统计信息:(表统计信息,索引统计信息及各列统计信息)

表的连接方式:nsloophash join,排序合并连接

 

nsloop

适合场景:小表驱动大表,驱动表结果集比较少,被驱动表的关联条件选择行比较高,最好走(index unique scanindex range scan),返回较少的结果集

 

hash join

适合场景:返回的结果集比较大,同样还是小表驱动大表

 

统计信息:表,缩影,各字段,直方图

索引扫描方式:索引唯一扫描,索引范围扫描,索引全扫描,索引快速全扫描,索引跳跃扫描

表扫描方式:全表扫描,单分区扫描,部分分区扫描

查询优化器:子查询非嵌套,视图合并,谓词推进

按照上诉的各种信息,查询优化器进行各种计算(算出各种场景的cbo),得出最优的执行计划

 

常见的sql优化:

当遇到复杂的查询时(层次查询,union all等)将会固定查询计划,这时候就需要sql改写。

insert 直接路径插入及并发

update使用merge into

delete删除大量数据时,分批提交。

存储过程使用批量操作bluck into forall组合。

 

如果library cache中能找到sql对应的hash值,上述12345步骤可直接跳过

6)按照执行计划去提取数据

首先查看sga中是否存在所需的数据,如果没有,需要读取磁盘,将相关数据加载到内存中。

将满足条件的数据行copypga,返回给用户。

数据加载到内存:

sga

lru链表,当数据块被加载到sga中,负责分配数据块到那个地方及覆盖那些不常用的数据块。

链表存在冷端和热端

冷端包含可用的内存和一些不常被访问的数据

热端是时常被访问的数据

当有数据需要被加载到内存中时,首先扫描lru链表查找是否存在可用的内存块。

tch大于2

脏块数据

正在被pin的数据块

上述数据块不能被覆盖。

当扫描超过一定范围时,就会触犯free buffer wait等待事件,该等待事件会触发dbwr进程写脏块。

hash链表:

clipboard.png

逻辑读:

用户从内存中读取所需的数据时,数据在内存中会按照hash算法分配到不同的bucket中,

为了保护内存的数据结构,会引入一个latch锁来保护。一个latch可能保护多个bucket

所以当sql查询的结果集较多或频繁的修改某个数据块时,会引起latch的争用。

访问数据块latch是独占的

访问索引是共享的(索引唯一扫描,rowid方式)

常见的等待事件为:latch buffer cache chain(热块或者热链)

sql优化(减少结果集,隐藏参数生成更多的bucket),热快(缓存等 ··

 

buffer busy wait(数据块,undo块,索引块)

常见与

当修改某个数据块,该数据块正在被其他会话占用。基本都是dml语句造成。

大并发量的insert插入。提高高水位

 

如果sql语句是dml语句,将内存中需要数据块copy一份,并且在块头事务槽中插入事务相关信息,对数据进行修改。(以前的内存块就是cr块)

将变更的信息(修改的数据内容,及源数据内容,undo相关信息)写入redo bufferlgwr进程负责将log buffer内容持久化。

 

lgwr触发条件:

3秒一次

log buffer1m

dbwr触发lgwr

会话commit

 

redo

常见的等待事件:log file sync(数据库事务多,redo磁盘性能差)

                             redo logfile文件太小(默认50m,增加redo logfiel大小)

awr

clipboard.png

查看log file parallel writeavg wait判断是否是磁盘性能问题

增加log buffer大小

 

undo

快照过旧,增加undo表空间的保留时间

将大事务切割成小事务,减少对undo表空间的使用

分配原则:

undo表空间充足的情况下,为每个事务单独分配独立的回滚段

undo表空间不足时,会覆盖超时的表空间,

还是不足,则会自动扩展表空间。

 

share pool是当前oracle 内存中最容易发生问题的地方。

share pool结构如下:

clipboard.png

 

clipboard.png

 

clipboard.png

 

clipboard.png

硬解析:latch share pool library cache:mutex x,latch:row cache objects

软解析:cursor:mutex x cursor: mutex S

软软解析:cursor: pin X cursor: pin S cursor: pin S wait on X

存储过程编译:library cache lock library cache pin cursor: pin S wait on X

oracle

队列锁

enq: TX - row lock contention

enq: TX - allocate ITL entry

enq: TX - index contention

enq:tm

enq:sq  序列未使用缓存

enq:sv   序列需要排序

enq:hw

内存锁

latch:buffer cache chain

latch:share pool

library cache lock

library cache:mutex x

library cache:curson x

library cache:pin s

 

生产环境案例分析:

某业务拼接了一个sqlsql20w行,导致sql一直卡在解析那个步骤,同时占用相关的对象资源未释放,导致其他会话解析相关的对象时,发生等待。查看v$session视图的blocking_session会话源头就是正在解析的那个sql

当时相关的等待事件:library cache:mutex xlibrary cache lock

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/muzisanshi/p/12910725.html