注册
达梦DM8数据库索引分类、适用场景、基础使用语法
技术分享/ 文章详情 /

达梦DM8数据库索引分类、适用场景、基础使用语法

畴野清风 2026/06/04 45 0 0

达梦索引主体分为B + 树系列索引(聚簇 / 普通 / 唯一 / 复合 / 函数)、位图索引、位图连接索引、HASH 索引、全文索引、空间索引六大类,OLTP 多用 B + 树,OLAP 数仓优先位图。

1 索引六大类

1.1 B+树索引(最常用,默认类型)
B + 树有序存储,支持等值、范围、排序、分组,OLTP 业务首选,分为 5 个子类:
1.1.1 聚簇索引 CLUSTER INDEX
规则:一张普通表只能 1 个聚簇索引,数据物理顺序 = 索引键顺序;主键默认自动生成聚簇索引;堆表 / 列存储表不能建聚簇索引。
 适用场景
1)主键字段;
2)高频范围查询字段(日期、自增 ID);
3)频繁 ORDER BY、RANGE 筛选列
 语法
sql
–建表主键自动生成聚簇索引
CREATE TABLE t1(id INT PRIMARY KEY,name VARCHAR(50));
–手动新建聚簇索引(会删除原有聚簇,重排全表数据)
CREATE CLUSTER INDEX idx_clu ON t1(id);
–删除聚簇:DROP INDEX idx_clu; 表自动改为 ROWID 物理排序
1.1.2 普通非聚簇 B 树索引(单列索引)
叶子存【索引键 + 聚簇键】,查非索引字段需要回表;一张表可建多个。
 适用:WHERE 等值过滤、JOIN 关联字段
sql
CREATE INDEX idx_t1_name ON t1(name);
1.1.3 唯一索引 UNIQUE INDEX
索引键全局唯一,允许单列 NULL,主键约束自动生成唯一 + 聚簇索引。
 适用:身份证、手机号、业务编码等唯一性字段
sql
CREATE UNIQUE INDEX idx_card ON t1(card_no);
1.1.4 复合(组合)索引
多列联合 B 树,遵循最左前缀匹配原则,跳过首列索引失效。
 适用:多字段联合 WHERE、分组统计;查询字段可全部包含在索引 =覆盖索引,无需回表
sql
–常用查询字段放左侧
CREATE INDEX idx_dept_sal ON emp(dept_id,salary);
–有效:where dept_id=10 and salary>5000
–失效:where salary>5000(跳过首列dept_id)
1.1.5 函数索引(表达式索引)
基于函数/运算表达式预计算结果建 B 树,查询条件必须和索引表达式完全一致才走索引,避免隐式转换失效。
 适用:经常用函数做条件:大小写转换、日期运算、JSON 取值、四则运算
sql
–常规函数索引
CREATE INDEX idx_up_name ON t1(UPPER(name));
–JSON字段索引
CREATE INDEX idx_json_city ON t(JSON_VALUE(addr,’$.city’));
–运算表达式索引
CREATE INDEX idx_sal_after ON emp(salary*0.8);

–生效写法:WHERE UPPER(name)=‘ZHANGSAN’
–失效写法:WHERE name=UPPER(‘zhangsan’)
1.2 位图索引 BITMAP(数仓 OLAP 专用)
 特性
按字段不同值生成位图,位运算(与 / 或)快速多条件筛选;更新 DML (INSERT/UPDATE/DELETE) 锁表严重,禁止 OLTP 频繁更新表使用。
 适用:低基数字段(取值少):性别、状态、类型、年份;多字段组合筛选、COUNT 统计;数据仓库大表
 禁用场景:频繁增删改、主键 / 唯一字段、MPP 集群不支持位图索引
sql
CREATE BITMAP INDEX idx_bit_gender ON user_info(gender);
–多字段组合位图筛选:where gender=‘男’ and status=1
1.3 位图连接索引 BITMAP JOIN INDEX
数仓星型模型专用,预先存储事实表 + 维度表关联结果的位图,优化多表关联统计,极少在 OLTP 使用。
sql
CREATE BITMAP JOIN INDEX idx_bj ON fact(user_id) FROM fact,dim_user WHERE fact.user_id=dim_user.id;
1.4 HASH 索引
 特性
哈希映射,只支持等值查询 =,不支持 > < BETWEEN 范围;等值查询性能优于 B 树,无排序能力。
 适用:纯等值查询、内存表、字典码字段
sql
CREATE HASH INDEX idx_hash_id ON t(id);
 环境限制
版本限制:DM7 全版本不支持 HASH 索引;只有DM8 企业版 >=1.2支持 HASH,标准版 / 试用版无 HASH
MPP/DSC 集群禁用 HASH,集群环境任何表都无法创建 HASH 索引
永久普通堆表 (NOBRANCH 永久表) 不支持 HASH,只有 GLOBAL 临时堆表支持 HASH 索引
1.5 全文索引 FULLTEXT
针对 TEXT/VARCHAR 大文本,支持模糊分词、全文检索(like%% 低效场景)。
sql
CREATE FULLTEXT INDEX idx_ft_content ON article(content);
SELECT * FROM article WHERE CONTAINS(content,‘达梦数据库’);
 环境限制
1)DSC 集群:缺少分词库SYSWORD.UTF8.LIB,全文索引隐藏;
2)HUGE 超大表、分区表:不支持全文索引;
3)临时表、外部表:无法创建全文;
4)全文索引只能建在 VARCHAR/TEXT/CLOB 文本字段,如果表全是 INT/NUMBER 数值字段,管理工具自动隐藏全文索引;
5)版本限制:DM7 全版本无 HASH 索引,只有 DM8.1.2 及以上企业版才有 HASH。

1.6 空间索引 SPATIAL
GIS 地理字段(POINT/LINE/POLYGON)专用,空间相交、包含、邻近查询。
sql
CREATE SPATIAL INDEX idx_sp ON gis_tab(loc);

2 索引常见问题

2.1 索引建了,但查询不走索引(最常见)
1)字段上用了函数 / 运算 → 索引失效
sql
WHERE UPPER(name) = ‘A’ – 不走普通索引
WHERE SUBSTR(name,1,2)=‘AB’ – 不走
WHERE age+1 = 20 – 不走
解决:建函数索引
sql
CREATE INDEX idx ON t(UPPER(name));
2)隐式类型转换(字符串 vs 数字)
sql
WHERE phone = 13800138000 – phone是VARCHAR,传数字 → 索引失效
解决:类型一致
sql
WHERE phone = ‘13800138000’
3)模糊查询 %前缀
sql
WHERE name LIKE ‘%张’ – 不走索引
WHERE name LIKE ‘张%’ – 走索引
解决:用全文索引,或改后缀模糊。
4)复合索引不满足最左前缀
索引 idx(a,b,c)
sql
WHERE b=1 AND c=2 – 跳过a → 不走索引
解决:查询必须包含索引最左列。
5)数据量太少 → 优化器选择全表扫描
小表(几百行)达梦会自动不走索引,正常现象。
2.2 客户端创建索引的选择框中看不到某些索引类型
1)看不到位图索引
原因:表是聚簇表(有主键)
→ 位图只支持堆表(FLAT)
解决
sql
CREATE TABLE t(…) STORAGE(NOBRANCH); – 堆表
2)看不到 HASH 索引
原因:
HASH 只支持临时堆表,永久表不支持
企业版才有
MPP 集群禁用
3)看不到 全文索引
原因:
字段不是 VARCHAR/TEXT/CLOB
参数 ENABLE_INDX_CTX=0
集群缺少分词库
2.3 索引导致 DML 变慢(insert/update/delete 卡)
原因:
表上索引越多,写操作越慢(每写一次就要更新所有索引)
常见场景:
日志表、流水表建了大量索引 → 插入极慢
位图索引用在 OLTP 表 → 锁等待、死锁
解决
少建无用索引
日志表不要建多余索引
位图只能用于 OLAP 静态表,不能用于业务高频更新表
2.4 聚簇索引(主键)常见坑
1)用 UUID 做主键 → 性能极差
UUID 无序 → 聚簇索引频繁页分裂,插入超慢。
解决
用自增 INT/BIGINT 做主键。
2)主键太长(字符串很长)
二级索引都会存主键 → 索引巨大,内存暴增。
解决
主键用短数字类型。
2.5 索引失效(状态无效)
查看无效索引:
sql
SELECT INDEX_NAME,STATUS FROM USER_INDEXES WHERE STATUS=‘INVALID’;
原因:
字段被修改
函数索引依赖的函数变了
表数据大量变动
解决
sql
ALTER INDEX idx REBUILD;
2.6 创建索引时报错
1)建位图报错:不支持聚簇表
plaintext
聚簇表不能建位图 → 必须改成堆表
2)建 HASH 报错:语法错误
plaintext
永久表不能建 HASH → 只能建在临时堆表
3)建全文索引报错:文本类型不支持
plaintext
必须 VARCHAR/TEXT/CLOB
2.7 索引碎片越来越大,查询变慢
大量 update/delete 后索引出现碎片。
解决
sql
ALTER INDEX idx REBUILD;
2.8 最实用总结(背会就不踩坑)
函数、运算、隐式转换 → 索引必失效
聚簇表不能建位图,永久表不能建 HASH
小表不走索引正常
索引越多,写入越慢
复合索引遵循最左前缀
like ‘% xxx’ 不走索引
无序主键(UUID)会毁掉聚簇表性能

3 索引使用要点

3.1 适合建索引
 WHERE、JOIN、ORDER BY、GROUP BY 频繁出现字段;
 高基数字段(唯一值多)建 B 树,低基数 (枚举值) 数仓建位图;
 小表 (<千行) 一般不建索引,全表扫描更快。
3.2 不建议建索引
 更新极频繁 (高频 INSERT/UPDATE):索引维护开销大;
 字段大量 NULL、基数极低 (如只有 0/1) 且 OLTP 频繁更新;
 模糊查询%xxx前置通配无法走普通 B 树,改用全文索引。
3.3 常用索引运维 SQL
sql
–查看表所有索引
SELECT INDEX_NAME,INDEX_TYPE FROM DBA_INDEXES WHERE TABLE_NAME=‘T1’;
–重建索引(碎片过多优化)
ALTER INDEX idx_name REBUILD;
–删除索引
DROP INDEX idx_name;
–在线建索引(业务不停机,DM8支持ONLINE)
CREATE INDEX idx ON t(col) ONLINE;

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服