You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Oracle索引压缩参数选择:COMPRESS 3还是COMPRESS 2?

Oracle索引压缩:COMPRESS 2 vs COMPRESS 3 及selected_person_id列压缩分析

结合你的表数据分布和查询场景,我来逐一拆解问题:

一、选COMPRESS 2还是COMPRESS 3?

首先得明确Oracle索引压缩的核心逻辑:COMPRESS N 是对索引的前N-1列的重复前缀组合进行压缩,后缀列(第N列及以后)不会参与压缩。

结合你的数据和查询需求:

  • 索引前缀(status, process_name)的重复率很高:status仅10个不同值,process_name有23个,二者的理论组合最多230种,实际数据中同一status+process_name必然对应大量重复行(因为后续的nvl(selected_person_id,-1)有大量不同值或空值转成的-1)。
  • COMPRESS 3会把(status, process_name)的重复组合只存储一次,后续的nvl(selected_person_id,-1)作为后缀列存储,能大幅减少索引存储空间,同时索引体积变小后,查询时的IO开销也会降低。
  • COMPRESS 2仅压缩status列的重复值,process_name作为后缀的一部分,压缩效率远低于COMPRESS 3——毕竟status只有10个值,能节省的空间非常有限。

唯一需要权衡的是写入开销:压缩会增加插入/更新时的CPU消耗,但如果这张表不是高频写入(比如每秒数百上千次的DML操作),这点开销完全可以接受,换来的是更小的索引体积和更优的读性能。

二、是否适合压缩selected_person_id列?

结论是:不适合,原因如下:

  • 经过nvl(selected_person_id, -1)处理后,该列有17419个不同值,加上18891行的-1,整体基数很高,重复率极低(即便-1占比约30%,但它的前缀是(status, process_name),同一前缀下的-1分散在不同组合里,重复的前缀+第三列的组合并不多)。
  • 若要压缩这一列,需使用COMPRESS 4,此时压缩的前缀是(status, process_name, nvl(selected_person_id,-1)),这个组合的重复率极低,几乎不会带来任何空间节省,反而会让DML的CPU开销进一步增加,得不偿失。
  • 不过把这一列加入索引是合理的:当你的查询加上nvl(psth.selected_person_id, -1) in (:p_person_id, -1)条件时,索引可以直接定位到目标行,避免回表操作。

额外验证建议

可以做个小测试来确认最优选择:

  1. 创建两个测试索引:
    create index xxhr_api_transactions_idx1_comp2 on hr.hr_api_transactions (status, process_name, nvl(selected_person_id, -1)) compress 2;
    create index xxhr_api_transactions_idx1_comp3 on hr.hr_api_transactions (status, process_name, nvl(selected_person_id, -1)) compress 3;
    
  2. 对比两个索引的大小:
    select index_name, round(bytes/1024/1024, 2) as size_mb 
    from dba_indexes 
    where index_name in ('XXHR_API_TRANSACTIONS_IDX1_COMP2', 'XXHR_API_TRANSACTIONS_IDX1_COMP3');
    
  3. 用你的查询语句查看执行计划,对比两个索引的逻辑读和执行效率。

实际测试的结果会是最准确的判断依据,但基于你的数据分布,COMPRESS 3应该是更优的选择。

内容的提问来源于stack exchange,提问作者Superdooperhero

火山引擎 最新活动