Oracle 大表创建索引

祖仙教小凡仙 海鲨数据库架构师

有个2亿记录的表,发现需要添加一个联合索引,结果就采用普通的create index index_name on tablename (entp_id,sell_date),结果悲剧了,把所有的DML语句都阻塞了,导致系统不能正常使用,还好是晚上10点,用户不是非常多,1个小时候,索引结束,阻塞解决;上网查了一下,如果加上 online参数后,就可以在线做索引,而不需要阻塞所有的DML语句,血的教训,拿出来与各位共勉,

创建测试表

* create table t_test

* (

* col1 number,

* col2 number

* );

造测试数据(根据自己机器具体情况估计需要的数据量,使创建索引的时间大概在20-30秒)

insert into t_test

select rownum col1, rownum col2 from dual

connect by rownum<10000000;

commit;

create index

会话1:

SQL> set time on

10:22:01 SQL> set timing on

10:22:02 SQL>

--获取 会话1 sid

10:22:04 SQL> select sid from v$mystat where rownum=1;

SID

144

Elapsed: 00:00:00.01

会话2:

SQL> set time on

10:22:06 SQL> set timing on

10:22:06 SQL>

--获取 会话2 sid

10:22:06 SQL> select sid from v$mystat where rownum=1;

SID

147

Elapsed: 00:00:00.01

会话3:

SQL> set time on

10:22:11 SQL> set timing on

10:22:11 SQL>

--格式化输出

10:22:13 SQL> set line 200

10:23:03 SQL> col addr for a10

10:23:03 SQL> col kaddr for a10

10:23:03 SQL> col sid for 999999

10:23:03 SQL> col type for a10

10:23:03 SQL> col id1 for 99999999999

10:23:03 SQL> col id2 for 99999999999

10:23:03 SQL> col lmod for 99

10:23:03 SQL> col request for 99

10:23:03 SQL> col ctime for 999999

10:23:03 SQL> col block for 99

10:23:03 SQL> col table_name for a30

10:23:03 SQL>

会话1:

--创建索引(因为要在 会话2、会话3 中做其它操作,所以表中数据要量要足够大)

10:25:08 SQL> create index ix_test_col1 on t_test(col1);

Index created.

Elapsed: 00:00:59.73

会话2:

--修改指定行的索引字段,此时update语句会hang住,等待索引创建,从会话3 中的锁的情况可以看到 会话2 在等待 会话1

10:25:04 SQL> update t_test set col1=102400 where col2=102400;

1 row updated.

Elapsed: 00:01:02.63

会话3:

--查看此时锁的情况

10:24:29 SQL> select a.*, decode(a.type, \'TM\', b.object_name) table_name

from v$lock a, dba_objects b

where a.id1=b.object_id(+)

and a.sid in(144, 147);

SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK TABLE_NAME

144 TM 18 0 3 0 1 0 OBJ$

147 TM 5180637 0 0 3 0 0 T_TEST

144 TM 5180637 0 4 0 3 1 T_TEST

144 DL 5180637 0 3 0 3 0

144 DL 5180637 0 3 0 3 0

144 TX 655384 57423 6 0 3 0

6 rows selected.

Elapsed: 00:00:02.12

10:25:52 SQL> /

这里看到普通索引创建 要加TM TX DL 三把锁,更新语句正在等待要加TX锁

SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK TABLE_NAME

147 TM 5180637 0 3 0 4 0 T_TEST

147 TX 393221 56619 6 0 4 0

Elapsed: 00:00:00.77

当索引创建完 了后 更新语句才加到锁.

因此普通索引创建的时候 会阻塞 索引字段上的DML操作! 主要是因为不喜欢别的会话更改索引字段的值,否则导致索引叶节点的键值与表数据不一致.

create index online

会话1:

--删除索引,并加online选项重建

10:26:46 SQL> drop index ix_test_col1;

Index dropped.

Elapsed: 00:00:00.35

10:26:59 SQL> create index ix_test_col1 on t_test(col1) online;

Index created.

Elapsed: 00:02:47.07

会话2:

--修改指定行的索引字段,此时update不会待索引创建,而是很快结束

10:26:50 SQL> update t_test set col1=102400 where col2=102400;

1 row updated.

Elapsed: 00:00:09.21

会话3:

--查看锁的情况

10:26:53 SQL> /

SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK TABLE_NAME

147 TM 5180637 0 3 0 6 0 T_TEST

144 TM 5180637 0 2 0 7 0 T_TEST

144 DL 5180637 0 3 0 8 0

144 DL 5180637 0 3 0 8 0

144 TM 5180671 0 4 0 7 0 144 TX 327692 57125 6 0 8 0

147 TX 655370 57432 6 0 6 0

7 rows selected.

Elapsed: 00:00:02.16

这里看到DML语句也加到了TX锁,而索引也加了3把锁.

.online创建索引时会临时创建一个IOT的表,把后期DML 记录到该表中,索引创建结束后删除IOT表 事实上就是类似于MVCC 回滚段的味道

oracle创建索引表,Oracle 大表创建索引相关推荐

  1. oracle 表连接 大表小表_优化必备基础:Oracle中常见的三种表连接方式

    在Oracle SQL语句中,如果from后面有多个表时,表的连接方式是一个很重要的考量. 从Oracle 6开始,优化器就支持下面4种表连接方式: - 嵌套循环连接(Nested Loop Join ...

  2. Mysql之小表驱动大表

    Mysql之小表驱动大表 1 什么是小表驱动大表 2 为什么使用小表驱动大表 3 判断驱动表与非驱动表 4 Exists和in的使用场景 1 什么是小表驱动大表 用小的数据集去驱动(可理解为匹配)大的 ...

  3. MySQL IN、Exist关联查询时,我们为什么建议小表驱动大表?

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  4. Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++){} }for($i = 0; $i < ...

  5. MySql小表驱动大表

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  6. mysql算法优化原则_Mysql优化原则_小表驱动大表IN和EXISTS的合理利用

    //假设一个for循环 for($i = 0; $i < 10000; $i++) { for ($j = 0; $i < 50; $j++) { } } for($i = 0; $i & ...

  7. MySQL关联查询时,我们为什么建议小表驱动大表?

    作者:留兰香丶 blog.csdn.net/codejas/article/details/78632883 有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们 ...

  8. NL连接一定是小表驱动大表效率高吗

    前言 两表使用nest loop(以下简称NL)方式进行连接,小表驱动大表效率高,这似乎是大家的共识,但事实上这是有条件的,并不总是成立.这主要看大表扫描关联字段索引后返回多少数据量,是否需要回表,如 ...

  9. mysql 小表连大表_MySQL 表之间关联查询时,为什么建议小表驱动大表?

    有的时候我们在操作数据库时会将两个或多个数据表关联起来通过一些条件筛选数据,在关联表时我们要遵循一些原则,这样会使我们编写的SQL 语句在效率上快很多. 一.优化原则 小表驱动大表,即小的数据集驱动大 ...

  10. MySQL小表join大表的正确使用姿势(straight_join 关键字的使用)

    网上有种说法是:由于一般是采用小表join大表的方式(可以提高效率),所以有人说将小表放在左边,让它先执行,记住,这种说法是错误的!!!有例为证: 我们看上例: film inner join fil ...

最新文章

  1. php-fpm的pool、php-fpm慢执行日志、open_basedir、php-fpm进程管理
  2. 虚拟机配置网络eth1
  3. Dokcer安装Redis
  4. last_kmsg和ram console
  5. linux mysql安装_LINUX 安装 MYSQL
  6. linux账户初始化文件,Linux启动初始化配置文件浅析
  7. java synchronizer_Java同步框架AbstractQueuedSynchronizer详解
  8. php大转盘,php大转盘
  9. [JavaScriptC#]收藏 备忘
  10. ORACLE 登录相关的信息
  11. java applog_个人app如何收集用户日志
  12. Appium自动化下拉刷新
  13. 文献阅读笔记:北极气溶胶与气候
  14. Java使用三层架构、JDBC连接数据库完成《试题信息管理系统》
  15. 82.【LibraryManger】
  16. python音频转文字腾讯_使用Python三步完成文本到语音的转换
  17. APP地推的一些经验
  18. Python基础1:数据类型、序列
  19. docker inspect container_name | grep Mounts -A 20
  20. 遥感IDL二次开发(辐射定标)

热门文章

  1. mac使用jvm诊断工具arthas启动报错Can not find tools.jar under java home解决
  2. 不一定联发科!苹果5G基带尚未敲定:高通/Intel还有机会
  3. linux 关闭进程脚本
  4. c语言入门经典 脚本之家,一个不错的shell 脚本教程 入门级_其它_脚本之家
  5. 关于编程语言的思考——编译型和解释型
  6. python中rest是什么意思_Python语言之RESTframework简介
  7. [Network] 计算机网络基础知识总结
  8. 【Java】JVM 知识串讲
  9. 【Unity】Hololens第三视角(Spectator View)preview 版(ipad或者iphone版) 实现及踩坑记录
  10. 用tornado爬素材网站