1、v$lock中id1和id2
tx时能看事务的位置,
tm时能看对象的id
(1)当锁的TYPE为TX时
XIDUSN(回滚段编号)=( ID1值 /65536)=6
XIDSLOT(槽位号)=mod( ID1值,65536)=8
XIDSQN(序列号)=ID2
所以通过ID1可以换算出当前事务的回滚段编号和槽位号,而ID2则为序列号。
(2) 当锁的TYPE为TM时,ID1为对象号,ID2通常为0。
select object_name from user_objects where object_id='ID1';
通过ID1可直接查出当前操作对象的相关信息。
2、不借助awr看cost等
(1)v$sqlstat:
V$SQLSTATS.BUFFER_GETS, for high CPU
V$SQLSTATS.DISK_READS, for high I/O
V$SQLSTATS.SORTS, for many sorts
(2)一个SQL一个时候是只有一个计划,v$sql_plan当然只有一条
但是dba_hist_sqlstat会统计过去执行过的计划. 所有在dba_hist_sqlstat有多个执行计划.
3、sql变慢问题
(1)os cpu/mem/io
(2)db redo/undo/temp/io/arch/mem/内存抖动/其它sql影响库整体
(3)利用xl.sql、longkf、等脚本
看会话数、行锁、长sql等
(4)DBA_HIST_SQL_PLAN.PLAN_HASH_VALUE
(5)执行计划arows/erows
(6)10053看谓词、cost等
(7)sql变慢的干预:
hint
outline
sql_profile
Sql Plan Management/baseline
收集/锁定统计信息
使用STA优化SQL
4、小刚优化经历:
(1)大表嵌套加hint变hash
(2)子查询改成with as
(3)高频率小表keep到内存
(4)改为分区表
(5)收集表和索引统计信息/直方图
(6)增加where条件
(7)缩小程序传参的默认值范围
(8)并行查询
(9)直接路径读
(10)清历史shrink space降高水位
5、紧急处理死锁问题:
(1)看会话间blocking关系,
用我电脑上vs.sql,as.sql脚本
特别方便
(2)@spid通过sid.serial查spid
(3)@full通过sqlid查fulltext
(4)让业务确认要杀的sql
(5)@kill分别在各rac节点上杀spid
6、写优化:
(1)nologging(有时影响备库)
(2)分批,大事务改成小事务
(3)空闲时间,大批量导数放到晚上
(4)大批量清历史数据放到周五晚至双休,及时清归档
(5)并行
(6)/*+ append */
(7)如果可能:关归档
6、10g同用户多会话共用同临时表空间,因为用户只一默认临时表空间。
为了解决这个潜在的瓶颈,11g支持的临时表空间组,逻辑上相当于一个临时表空间。
7、lib cache
(1)包含游标、执行计划等
(2)未绑定变量循环执行、改对象信息,执行计划失效,出现lib cache lock?
(3)lib cache对象的定位
handle关联 head0(对象名、spin)
hash bucket/hash chain争用/lib cache obj
8、a/b/c会话锁冲突
(1)有环路有死锁有trace文件
能看被blocking的sql
(2)无环路无死锁无trace文件
也能看到被blocking的sql(因为sql已经过语法解析、语义解析、终执行)
(3)监测时间是由隐含参数_lm_dd_interval控制,
在11g中的值默认为10/秒
在10g中默认为60/秒。
9、建索引有什么注意点?
(1)是否建索引
选择性高建索引
有排序尽量建索引
打印20%左右建索引
打印超30%不如走全表
(2)复合索引的引导列
选择性好的列放前面
调用多的列放前面
(3)函数索引(比如where upper)
(4)位图索引(重复值很多的)
(5)操作注意事项
加online
非繁忙时段
OLTP索引不宜过多
10、execution key
(1)SQL Execution ID
对于不同的SQL语句的执行,通过SQL_ID可以区分;
同一语句,在同一实例上,每执行一次,SQL_EXEC_ID增加1,与执行的用户和session无关。
对于同一SQL语句(SQL_ID相同)的执行,需要通过SQL_EXEC_START和SQL_EXEC_ID区分。
(2)V$SESSION.SQL_EXEC_START 获取一个ing的SQL执行了多长时间。
11、enq:TX - index contention等待事件(索引分裂竞争)
(1)通常情况下分裂一个索引块是毫秒级的,如果某个会话长时间持有锁,也就是说该会话分裂索引块时间长,那么就需要查该会话的等待事件和读取的对象,很可能是在位图块中寻找一个可用的空块而消耗了更多的时间;
解决办法: 定期重建索引
(2)应用程序并发数大时导致了热块竞争,通常伴随着gc类的等待一起发生;
解决办法: 创建反向键索引或还可以将索引改造为HASH分区;
(3)RAC中私网流量大或者传输时有丢失的情况而导致不能快速申请到空的索引块,通常伴随着gc类的等待一起发生。
解决方法:如果是私网流量大就需要分析SQL是否可以优化,如果是网络有丢包现象就需要通过系统网络层分析。
12、全局非分区索引、全局分区索引
(1)全局非分区索引
为普通表或分区表建立普通索引。
(2)全局分区索引
索引分区键可以跟表分区键不一致,但索引的索引键前缀要包含索引的分区键。
CREATE INDEX i3 ON sales(month,date) GLOBAL PARTITION BY RANGE(month)
对分区表中的某个分区做truncate或者move,shrink等,可能会影响到n个全局索引分区,可用性降低。
(3)局部/本地分区索引
索引分区键等同于表分区键。
前缀局部索引索引列以分区键开头。
非前缀索引索引列不是以分区键开头,或者不含分区键列。
create table t (id ,data)
partition by RANGE (id)
create index i1 on t(id) local; 前
create index i2 on t(data) local;非
13、CDB与PDB
和SQL SERVER的单实例多数据库架构是一回事
14、表碎片
(1)怎样确定是否有表碎片
确保统计信息新
用dba_tables脚本找出表碎片高的表
(2)为什么要整理表碎片
全表扫读高水位下的所有块
查询响应时间(尤其是全表扫描)变慢
产生大量行迁移
浪费空间
整理表碎片对基于索引的查询不会有太大性能提升。
(3)如何整理表碎片
10g之前
导出表,删除表,再导入表
alter table move(需要重建索引)
10g后
alter table shrink space;
(不需要重建索引。
可以在线操作。
不需要空闲空间,alter move需要跟当前表一样大小的空闲空间)
15、紧急定位当前问题sql
v$sql/v$sqlarea/v$session
(1)v$sql和v$sqlarea基本相同,记录了共享SQL区(share pool)中SQL统计信息,如内存消耗、物理读逻辑读、排序、哈希ID等(v$sqltext无统计信息有完整SQL及哈希ID等)。
(2)v$session主要用来确定会话相关信息,如正在执行什么SQL(SQL_ADDRESS、SQL_HASH_VALUE、SQL_ID、SQL_CHILD_NUMBER)、上次执行的SQL(PREV_SQL_ADDRESS)、锁等待(所在表、文件、块、被锁行)。
(3)查看高资源消耗SQL
读硬盘多或占用内存可能多的SQL: v$sqlarea(IO间接反映内存)
执行次数多的SQL:v$sqlarea
排序多的SQL: v$sqlarea
总耗时多的前10条SQL:v$sql
CPU耗时前10条SQL: v$sql
IO多的前10条SQL: v$sql
16、不通过awr查看sql的cost
v$sqlstat dba_hist_sqlstat
(1)v$sqlstat:
视图记录了实例启动以来存放在shared pool中的的所有已解析的SQL基本的统计信息,但是信息保留的时间比v$sql和v$sqlarea时间长,其中的数据是v$sql和v$sqlarea的子集。
V$SQLSTATS.BUFFER_GETS, for high CPU
V$SQLSTATS.DISK_READS, for high I/O
V$SQLSTATS.SORTS, for many sorts
(2)一SQL一时刻只有一个计划,v$sql_plan当然只有一条
(3)dba_hist_sqlstat会统计过去执行过的计划. 所有在dba_hist_sqlstat有多个执行计划.
17、事后查找引起性能故障的sql
(1)ASH每秒从v$session中取快照,存在V$ACTIVE_SESSION_HISTORY中,并收集所有活动会话的等待信息。
该视图是ASH的核心,用以记录活动SESSION的历史等待信息,每秒采样一次,这部分内容记录在内存中,期望值是记录一个小时的内容。
(2)若ASH数据被刷新到磁盘,则需要从DBA_HIS_ACTIVE_SESS_HISTORY视图中查询相关信息。
(3)举例:查找近10分钟内
消耗CPU的sql语句
消耗I/O的sql语句
消耗CPU的session
消耗资源的sql语句
消耗资源的session
18、标量子查询
(1)返回结果只有一行的子查询叫标量子查询。
(2)使用标量子查询可以有效的改善性能。
(3)常用于改写:
当使用到外部连接,或者使用到了聚合函数,就可以考虑标量子查询的可能性。
(4)标量子查询可以出现在select、where和having子句中。
(5)简举例:
列出所有系及它们拥有的教师数
select dept_name,
(select count(*)
from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from department;
上面例子中的子查询保证只返回单个值,因为它使用了不带group by的count(*)聚集函数。
动力小刚于2019年5月 个人邮箱:zcs0237#163.com