oracle生产环境实用技巧——在大表中创建索引
在上亿数据的大表上新建索引,是一个较为耗时的操作,特别是在生产环境的业务表,长时间的停服势必会影响正常业务的开展。结合笔者个人的实际经验,文章将介绍三种手段来帮助大家解决这个问题,需要注意的是这三种方法并不是独立使用的,很多时候我们会结合起来一起使用来提升建索引的效率。
环境说明
- oracle数据库版本 19c
(一)三板斧之——parallel 开启并发执行
并发执行可以最大程度的利用我们的数据库资源,把大批量的数据分成小批量到不同的节点上去执行,从而大大减少sql的执行耗时。由于建索引属于ddl操作,我们可以通过下面的语句来实现并发执行。
下面的语句中,我们就配置了使用并发值为8来执行我们的sql语句
CREATE INDEX idx_table1_column1 ON table1 (column1) PARALLEL 8
关于parallel的更多使用说明,可以看我写的这篇文章:Oracle并行执行——parallel关键字的使用
(二)三板斧之——nologging
我们知道数据表新增、修改、删除记录都可能会触发redo日志和undo日志的记录,特别是insert into table1 select * from table2
这种语句,每条insert动作都会同时生成redo日志和undo日志,从而降低sql的执行速度。对于创建索引的操作也是如此,索引的创建同样也涉及到这两类日志的记录,我们可以手动指定不记录非必要日志来加快sql执行的速度。
- 补充一下redo、undo日志的作用
1、undo日志:用于把数据恢复到回滚前的数据。在恢复时取消未完成事务的影响,忽略已经提交的事务
2、redo日志:用于把数据恢复到数据库指定节点的时候。忽略未完成的事务,重做已经提交事务的改变。
需要注意,nologging的核心在于只输入最少的redo日志(注意,这里不是不输出日志,只是最小化需要输入的日志量而已)
用法的话十分简单,只需要在我们创建索引的语句上加上nologging
关键字即可
CREATE INDEX idx_table1_column1 ON table1 (column1) nologging;
(三) 三板斧之——online(推荐使用)
前面介绍的两个命令虽然能大幅度提升效率,但归根结底建索引就是会导致锁表,不停服执行的话还是相当有风险的,online
的作用在于不阻塞DML操作,使得生产环境不会因为执行DDL语句导致业务功能阻塞,尤其适合于不停机新建表索引这类场景。
需要注意的是,online关键字的使用相对来说耗时会长一些,而且online关键字只能用于新增索引,并不能用在修改表结构等SQL语句中
online
的使用也十分简单,在sql语句后面加上online就行
CREATE INDEX idx_table1_column1 ON table1 (column1) online;
有了这三板斧,我们的最终的sql大概是这样的,有了online
可以保障不影响业务主流程的进行,而nologging
和parallel
则可以大幅度提高我们sql的执行速度,个人觉得是一种可行的解决方案。
CREATE INDEX idx_table1_column1 ON table1 (column1) parallel 8 nologging online;
var code = "1d5a1fe0-91b6-4b74-beae-68fcd3893e40"