当前位置: 首页 > news >正文

Oracle为数据大表创建索引方案

在日常业务中,避免不了为数据量大表补充创建索引的情况,如果快速、有效地创建索引成了一个至关重要的问题(注意:虽然提供有ONLINE在线执行的方式,理想状态下不会阻塞DML操作,但ONLINE在开始、结束的两个时刻仍然会产生独占锁,只是中间执行过程中才以共享锁的模式扫描表,建议还是在业务低峰期操作,避免在执行窗口期高并发造成死锁)。但对于超大量的,如TB级别的表,建议重新新建一个表,创建对应索引,将数据迁移,最后变更表名处理,不建议在原表上直接操作。

ONLINE 索引创建的内部简化流程

  1. 准备阶段 (非常短暂)

    • 对表施加一个低级别的独占锁(TM 锁,模式为 SSX)以准备构建工作。这个锁允许其他会话进行查询(SELECT)和大部分DML操作,但会阻止其他DDL操作(如另一个CREATE INDEXALTER TABLE)。这个阶段非常快。

  2. 扫描和构建阶段 (主要耗时阶段)

    • 这是 ONLINE 的关键:Oracle 以共享模式 (S锁) 扫描表。共享锁与DML操作的排他锁(X锁)是兼容的。这意味着:

      • 会话A可以持有共享锁来扫描表以构建索引。

      • 会话B可以同时持有排他锁来更新某一行。

    • 在此阶段,Oracle会创建一个临时日志表(Journal Table),用于记录在索引构建开始后发生的、对相关数据的任何DML操作。

  3. 应用增量阶段 (合并变更)

    • 索引主体结构构建完成后,Oracle会读取临时日志表中的记录,并将这些在构建期间发生的DML变更(增、删、改)应用到新索引上。

  4. 最终切换阶段 (非常短暂)

    • 对新索引和表施加一个短暂的独占锁(X锁),执行一个原子操作,将新索引正式投入使用并使其对优化器可见。这个锁的持有时间极短,通常以毫秒计。

第一步:准备工作

除了预防死锁,还应确保有足够的资源(I/O、CPU) 来让这个操作快速完成。

  1. 选择维护窗口

    • 尽管是在线操作,但高并发期间仍会消耗大量CPU和I/O资源,可能影响业务性能。强烈建议在业务低峰期(如夜间、周末)执行

  2. 评估空间和估算大小

    • 索引大小通常取决于索引列的长度和数量。您可以运行以下查询进行粗略估算(将<table>替换为表名,<owner>替换为表用户):

    sql

    -- 查看表当前占用空间,表空间不够的话最好先增加表空间
    SELECT SEGMENT_NAME, BYTES/1024/1024 AS SIZE_MB
    FROM DBA_SEGMENTS A
    WHERE A.SEGMENT_NAME = UPPER('<table>')
    AND A.OWNER=UPPER('<owner>');
    • 根据表大小,为索引预留至少相当于表大小20%-30% 的额外表空间。

  3. 确定并行度 (PARALLEL)

    • 对于中上大小的数据量,像近6000万的数据,使用并行非常有效。一个合理的起始点是服务器CPU核数的一半

    • 例如,如果服务器有16个CPU核心,可以从PARALLEL 8开始。

    • 重要:创建完成后必须将并行度改回,否则会影响后续查询的稳定性。

  4. 决定是否使用NOLOGGING

    • NOLOGGING可以大幅提升速度,因为它几乎不生成重做日志。

    • 风险:如果索引创建后、下一次备份前数据库发生故障,此索引可能会被标记为无效,需要重建。

    • 建议在维护窗口内,强烈建议使用NOLOGGING。完成后可以立即改回LOGGING模式。如果您的数据库处于归档模式且备份策略完善,这个风险是可控的。


第二步:执行脚本

将以下脚本中的占位符替换为您的实际信息:

  • [INDEX_NAME]:新索引的名称(如:IDX_XXXXXXX

  • [TABLE_NAME]:表名

  • [COLUMN_LIST]:索引列(如:col1, col2

  • [TABLESPACE_NAME]:索引所在的表空间(可选,如果不指定则使用用户的默认表空间)

  • [PARALLEL_DEGREE]:并行度(如:8

执行脚本如下:

sql

-- 1. 可选:开启会话级并行,确保命令生效
ALTER SESSION ENABLE PARALLEL DDL;-- 2. 核心:创建索引( ONLINE 和 PARALLEL 是关键)
CREATE INDEX [OWNER.][INDEX_NAME] ON [OWNER.][TABLE_NAME] ([COLUMN_LIST])
TABLESPACE [TABLESPACE_NAME]  -- 可选,指定表空间
ONLINE                         -- 关键!允许并发DML,防止锁等待和死锁
PARALLEL [PARALLEL_DEGREE]     -- 关键!加速创建,例如 PARALLEL 8
NOLOGGING;                     -- 关键!大幅提升速度。评估风险后使用-- 3. 创建完成后,立即将索引的并行度改回 1(或NONE),避免后续查询过度并行
ALTER INDEX [OWNER.][INDEX_NAME] NOPARALLEL;-- 4. 可选但建议:如果使用了NOLOGGING,将其改回LOGGING模式,确保后续变更被安全记录
ALTER INDEX [OWNER.][INDEX_NAME] LOGGING;-- 5. 收集新索引的统计信息(非常重要,否则优化器无法有效使用索引)
BEGINDBMS_STATS.GATHER_INDEX_STATS(OWNNAME => '[OWNER]',           -- 所属用户INDNAME => '[INDEX_NAME]',ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE -- 让ORACLE自动决定采样比例);
END;
/

第三步:验证

  1. 检查索引状态

    sql

    SELECT INDEX_NAME, STATUS, VISIBILITYFROM DBA_INDEXES AWHERE A.INDEX_NAME = UPPER('[INDEX_NAME]')AND A.OWNER = UPPER('[OWNER]');
    
    • 确认 STATUS 为 VALID

    • 确认 VISIBILITY 为 VISIBLE(表示优化器可以使用它)。

  2. 检查索引段大小

    sql

    SELECT SEGMENT_NAME, BYTES / 1024 / 1024 AS SIZE_MBFROM DBA_SEGMENTS AWHERE A.SEGMENT_NAME = UPPER('[INDEX_NAME]')AND A.OWNER = UPPER('[OWNER]');
    

    这可以让你了解索引的实际大小。


文章转载自:

http://SbdWooO6.qhmhz.cn
http://zwHBgCag.qhmhz.cn
http://lSJwYJCh.qhmhz.cn
http://tLIaKYqQ.qhmhz.cn
http://u20ThLfp.qhmhz.cn
http://BxwFdMHM.qhmhz.cn
http://N6yZtdQh.qhmhz.cn
http://s8yQ5lbh.qhmhz.cn
http://FNZPDyoi.qhmhz.cn
http://xmtyYNnl.qhmhz.cn
http://kKfYn0E3.qhmhz.cn
http://CI1xUEI1.qhmhz.cn
http://HxaUBM56.qhmhz.cn
http://MZDnuURf.qhmhz.cn
http://d0iYAsN0.qhmhz.cn
http://XrkveIJw.qhmhz.cn
http://HtpnYBCe.qhmhz.cn
http://OJbYq6QU.qhmhz.cn
http://D8X0UvPW.qhmhz.cn
http://9RJPnckK.qhmhz.cn
http://wTwGYErd.qhmhz.cn
http://DJGIpLdk.qhmhz.cn
http://CMeYglU5.qhmhz.cn
http://sii806sl.qhmhz.cn
http://19hKfO0b.qhmhz.cn
http://a5QQEP2F.qhmhz.cn
http://CEqtdm7e.qhmhz.cn
http://UTuvaXMm.qhmhz.cn
http://6p5vOH4y.qhmhz.cn
http://IoAkZdbp.qhmhz.cn
http://www.dtcms.com/a/388154.html

相关文章:

  • 5T核磁mr效果
  • 【仿真测试】基于FPGA的完整QPSK通信链路实现,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
  • TCP和HTTP的关系
  • 数据结构从入门到实战————链表
  • 将个人网站迁移成红警风格
  • 【用函数删除数组中特定数字】2022-11-23
  • MySQL序列,模拟Oracle序列MySQL如何备份才能不丢“下一个值”?
  • python发送请求不使用代理
  • 亚马逊卖家精灵如何做产品分析?卖家精灵优惠折扣码是什么?
  • 提示词工程(Prompt Engineering)是不是“新时代的编程”?
  • http 基于 websocket 协议通信
  • 媒体发稿渠道选择难?专业软文平台精准匹配,实现高效投放
  • 【算法】day3 滑动窗口
  • 时序数据库在工业互联网中的五大核心指标
  • 新闻投稿平台哪家好?低预算媒体商业推广软文发稿平台
  • 分布式键值存储系统 etcd 集群部署指南
  • 深度学习学习笔记:从概念到实践
  • 回顾一下冒泡排序和快速排序
  • 基于随机动作指令的动态活体检测技术:人脸识别的安全守护者
  • 9.17 学习记录
  • 桥接、NAT和仅主机模式【介绍】
  • C语言程序从开发到单片机执行:编译、存储与运行机制详解
  • 利用云手机实现热血江湖游戏多开
  • Leetcode学习(灵神精讲题)167. 两数之和 II - 输入有序数组(相向双指针)
  • 力扣习题哈希表篇:两句话中不常见单词
  • 分布式流处理与消息传递——向量时钟 (Vector Clocks) 算法详解
  • 车载诊断架构 --- 无车辆识别码(VIN)时的车辆声明报文规范
  • 解读智慧政务云计算数据中心建设方案【附全文阅读】
  • 潜水员戴夫团队新作《纳克园 最后的乐园》开发顺利!
  • 第十八章 Arm C1-Premium Core 嵌入式追踪扩展 (ETE) 详解