设为首页 收藏本站
查看: 1505|回复: 0

[经验分享] oracle之位图索引

[复制链接]

尚未签到

发表于 2016-7-19 11:33:08 | 显示全部楼层 |阅读模式
  位图索引适用于低基数(low-cardinality)列,所谓低基数列就是指这个列只有很少的可取值。
  位图索引的问题:
采用位图索引,一个键指向多行,可能数以百计甚至更多。如果更新一个位图索引键,那么这
个键指向的数百条记录会与你实际更新的那一行一同被有效地锁定。
  位图索引的适用场景:
位图索引是针对那些值不经常改变的字段的,在实际应用中,如果某个字段的值需要频繁更新,
那么就不适合在它上面创建位图索引。
  以下为针对位图索引的实验:
1.准备环节:
--创建一个表t
SQL> create table t(processed_flag varchar2(1));
  表已创建。
  --在表t的processed_flag创建一个位图索引
SQL> create bitmap index t_idx on t(processed_flag);
  索引已创建。
  2.在一个sql*plus会话中插入一行列值为N的记录,且先不commit;然后在另一个sql*plus会话中也
插入一行列值为N的记录,这时发现后面的会话会被阻塞。
--session1
SQL> insert into t values('N');
  已创建 1 行。
insert后不提交,则位图索引中的N键被锁住,任何DML语句只要与N有关都被阻塞
  --session2
SQL> insert into t values('N');
该语句被挂起
  --查询lock情况
这里有两个锁是正常的,因为任何DML操作都会产生锁,因为两个DML现在都没有commit,所以都会持有锁。
关键是看两个session的等待事件。可以看到前面的sid=146等待的是SQL*Net message from client,实际是
处于空闲等待,而sid=147等待的是enq: TX - row lock contention,其实是在等待sid=146释放其持有的锁
两个session持有的锁都为3-SX(Row-X)行级排它锁。
select t2.username,
t3.owner,
t3.object_name,
t2.machine,
t2.sid as sid,
t2.serial#,
t2.LAST_CALL_ET,
t2.program,
t1.locked_mode
from v$locked_object t1, v$session t2, dba_objects t3
where t1.session_id = t2.sid
and t1.OBJECT_ID = t3.object_id
order by t2.logon_time;

USERNAME OWNER OBJE MACHINE SID SERIAL# LAST_CALL_ET PROGRAMLOCKED_MODE
-------- -------- ---- ------------------------------ ---- ---------- ------------ -------------- ------------
SCOTT SCOTT T WORKGROUP\PC-200904261625 146 5 897 sqlplus.exe3
SCOTT SCOTT T WORKGROUP\PC-200904261625 147 12 894 sqlplus.exe3
  已选择2行。
  
--列出指定 ID 的等待事件
可见前面的session sid=146在等待客户端输入,实际上就是等待commit命令,而sid=147则是在等待enq: TX - row lock contention
select SID,EVENT from v$session_wait where sid=147;
  SQL> select SID,EVENT from v$session_wait where sid=147;
  SID EVENT
---- ----------------------------------------------------------------
147 enq: TX - row lock contention
  已选择 1 行。
  SQL> select SID,EVENT from v$session_wait where sid=146;
  SID EVENT
---- ----------------------------------------------------------------
146 SQL*Net message from client
  已选择 1 行。
  --查看当前被锁的 session 正在执行的 sql 语句
select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ a.username, a.machine, a.sid,
a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"
from v$session a, v$lock b, v$sqltext c
where a.username is not null and a.lockwait = b.kaddr and c.hash_value =a.sql_hash_value
  USERNAME MACHINE SID SERIAL# Seconds ID1 SQL
-------- ------------------------------ ---- ---------- ---------- ---------- ----------------------
SCOTT WORKGROUP\PC-200904261625 147 12 3006 327724 insert into t values('N')
  --session1 commit后,session2不再等待
SQL> insert into t values('N');
  已创建 1 行。
  
3.在一个sql*plus会话中插入一行列值为N的记录,且先不commit;然后在另一个sql*plus会话中
插入一行列值为Y的记录,这时发现二者互不影响。
--session1
SQL> insert into t values('N');
  已创建 1 行。
insert后不commit
  --session2
SQL> insert into t values('Y');
  已创建 1 行。
insert后不commit
  --查看lockqingk
可见两个session都持有锁,那么二者的等待事件是什么呢
select t2.username,
t3.owner,
t3.object_name,
t2.machine,
t2.sid as sid,
t2.serial#,
t2.LAST_CALL_ET,
t2.program
from v$locked_object t1, v$session t2, dba_objects t3
where t1.session_id = t2.sid
and t1.OBJECT_ID = t3.object_id
order by t2.logon_time;

USERNAME OWNER OBJE MACHINE SID SERIAL# LAST_CALL_ET PROGRAM
-------- -------- ---- ------------------------------ ---- ---------- ------------ --------------
SCOTT SCOTT T WORKGROUP\PC-200904261625 147 12 114 sqlplus.exe
SCOTT SCOTT T WORKGROUP\PC-200904261625 146 23 108 sqlplus.exe
  已选择2行。
  --查看等待事件
可见两个session都处于空闲等待
SQL> select SID,EVENT from v$session_wait where sid=146;
  SID EVENT
---- ----------------------------------------------------------------
146 SQL*Net message from client
  已选择 1 行。
  SQL> select SID,EVENT from v$session_wait where sid=147;
  SID EVENT
---- ----------------------------------------------------------------
147 SQL*Net message from client
已选择 1 行。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-246303-1-1.html 上篇帖子: Oracle lower(Upper)函数 下篇帖子: 如何dump oracle 内部结构
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表