sql server或者mysql innodb引擎,创建主键时候,默认的都是创建的聚集索引,达梦的默认策略为什么是让主键创建非聚集索引,有什么考虑么?
二级索引默认是非聚集索引,我这倒没什么疑问,我的疑问就是主键方面的。
创建聚集索引,以主键过滤记录,当查询到数据以后,可以不用回表,直接取到对应记录的所有列信息。主键作为非聚集索引,很多情况都需要回表,增加一次消耗。
我就好奇,达梦这么设计默认索引策略,有什么考量么?内部的实现,对于回表这方面有做了什么优化么?
您的陈述是有些道理的。
DM作为自主研发的国产数据库,可以兼容Oracle/sql server/MySQL等主流的国外数据库。
关于主键索引是否默认作为聚集索引提供了参数PK_WITH_CLUSTER控制,=1则默认为聚集索引,=0则非聚集索引,可根据需要调整参数实现对不同数据库的兼容。
以聚集主键列为谓词条件的查询,是可以避免回表,但现实并非这么完美:
一、
现在很多系统的表“主键”设计不良,特别是框架生成设计的表,很多表的主键是没有实际意义的,仅作为一个自增ID辅助标识唯一行,这种情况下增删改SQL也不会以主键为条件去检索数据,因此主键聚集索引就没有优势;
二、
很多表对数据最频繁的访问路径并不是主键列,而是类似于订单表里的账户ID、交易时间或者交易流水号,这些列数据是有可能重复的但却是系统访问最频繁的路径,这类表的聚集索引更多的倾向于使用“交易时间”列或者和其他列的组合,而不是主键;
三、
聚集索引使用有限制,一个表只能有1个聚集索引、不支持有大字段的表、不支持堆表和列存储表等;
当然,如果您的系统设计是DB为导向的,表的设计都是经过“专业”人士的,大多数表访问最频繁的路径就是主键,尤其是交易类的系统,不用犹豫,就把主键设置为默认聚集,即PK_WITH_CLUSTER=1。
ini参数里面有个PK_WITH_CLUSTER
select * from v$dm_ini where para_name = 'PK_WITH_CLUSTER';
这个参数是0就是表示主键默认非聚集,为1表示主键默认聚集。
考虑到后期方便对主键列进行修改(ddl修改)可以创建非聚集主键,如果后期基本不会修改主键列定义并且sql中会高频使用主键过滤可以创建成聚集索引
另外也可以在创建主键的时候显式指定为聚集或者非聚集,[NO] CLUSTER PRIMARY KEY...