一、索引选择性是什么?

在数据库系统中,索引选择性(Index Selectivity)是衡量索引效率的重要指标。简单来说,它表示索引列中不同值的比例。选择性越高,意味着索引列的唯一性越强,查询时过滤的数据就越多,索引的效果也就越好。

举个例子,假设我们有一张用户表 users,其中包含 genderuser_id 两列:

  • gender 列只有 "M" 和 "F" 两个可能的值,选择性很低。
  • user_id 列是唯一的,选择性为 1(最高)。

在这种情况下,user_id 上的索引会比 gender 上的索引更高效,因为前者能更精准地定位数据。

二、OceanBase 如何计算索引选择性?

OceanBase 提供了系统视图 __all_virtual_table_stat__all_virtual_column_stat,可以用来查看表和列的统计信息,包括索引选择性。

示例:查询索引选择性

-- 查看表的统计信息(OceanBase 4.x 版本)
SELECT 
    table_id, 
    table_name, 
    row_count 
FROM 
    __all_virtual_table_stat 
WHERE 
    database_name = 'test_db';

-- 查看列的统计信息(包含不同值的数量)
SELECT 
    table_id, 
    column_name, 
    num_distinct 
FROM 
    __all_virtual_column_stat 
WHERE 
    database_name = 'test_db' 
    AND table_name = 'users';

通过 num_distinctrow_count,我们可以计算选择性:

选择性 = num_distinct / row_count

示例:计算 users 表的选择性

假设 users 表有 10000 行数据:

  • gender 列有 2 个不同值,选择性 = 2 / 10000 = 0.0002(很低)。
  • user_id 列有 10000 个不同值,选择性 = 10000 / 10000 = 1(最高)。

这意味着,在 user_id 上建立索引更有价值。

三、如何优化索引选择?

1. 高选择性列优先

尽量在高选择性列上建立索引,例如唯一键、主键、或接近唯一的列(如手机号、邮箱)。

2. 组合索引的列顺序

如果是组合索引,应该把选择性高的列放在前面:

-- 假设 age 的选择性比 gender 高
CREATE INDEX idx_users_age_gender ON users(age, gender);

3. 避免在低选择性列上建索引

statusboolean 类型的列,通常只有几个可能的值,建立索引效果较差。

四、实际案例分析

假设我们有一个订单表 orders,包含以下字段:

  • order_id(主键)
  • user_id(用户ID)
  • status(订单状态:0-未支付, 1-已支付, 2-已取消)
  • create_time(创建时间)

查询场景:

-- 高频查询:查找某个用户的所有订单
SELECT * FROM orders WHERE user_id = 1001;

-- 低频查询:查找某个状态的所有订单
SELECT * FROM orders WHERE status = 1;

索引建议:

  1. user_id 选择性较高,适合单独索引。
  2. status 选择性低,不适合单独索引,但可以结合 create_time 建立组合索引:
CREATE INDEX idx_orders_status_time ON orders(status, create_time);

这样,查询 WHERE status = 1 AND create_time > '2024-01-01' 时可以利用索引。

五、注意事项

  1. 统计信息更新
    OceanBase 不会实时更新统计信息,如果数据分布变化较大,需要手动收集:

    ANALYZE TABLE users COMPUTE STATISTICS;
    
  2. 索引不是越多越好
    每个索引都会增加写入开销,需要权衡查询和写入的需求。

  3. 监控索引使用情况
    可以通过 EXPLAIN 查看查询是否真正使用了索引:

    EXPLAIN SELECT * FROM users WHERE user_id = 1001;
    

六、总结

索引选择性是衡量索引效率的关键指标,OceanBase 的系统视图可以帮助我们量化评估。在实际应用中,应该:

  • 优先在高选择性列上建立索引。
  • 合理设计组合索引的列顺序。
  • 避免在低选择性列上盲目建索引。
  • 定期更新统计信息,确保优化器能做出正确决策。

通过合理利用索引选择性,可以显著提升查询性能,降低数据库负载。