欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL索引设计需要考虑哪些因素?

程序员文章站 2022-06-25 08:21:04
索引小知识 篇幅有限,索引的基本知识我们就不赘述了,在此,我们尝试说明其中的一个小点 B+树与B树的区别到底是什么。 InnoDB是使用B+树来实现其索引功能的。在B+树中,内节点(非叶子节点)存储了行数据的键,而叶子节点存储了所有的行数据,而B树的每个节点都存储了真实的数据。这种数据结构,决定了两 ......

索引小知识

篇幅有限,索引的基本知识我们就不赘述了,在此,我们尝试说明其中的一个小点-----b+树与b树的区别到底是什么。

innodb是使用b+树来实现其索引功能的。在b+树中,内节点(非叶子节点)存储了行数据的键,而叶子节点存储了所有的行数据,而b树的每个节点都存储了真实的数据。这种数据结构,决定了两者有以下不同点:

(1)非叶子节点能存放指针的数据量。因为b树的非叶子节点存放的是整行的数据,占用了较多的空间,所以能存放指针就相对较少,因此整个b树的层数就变高。当数据量比较大时,插入更新会导致维护代价也是比较大的,而且层数越高,搜索的性能就会越低。而b+树的内节点存放的是相对短很多的键值,就克服了b树遇到的问题。

(2)从数据结构上来看,b树的查询效率与数据所在的位置有关。即如果所要搜索的数据节点,在树上的位置,越靠近根节点,查询返回结果越快,最差的就是数据位于叶子节点上,不同的节点位置,其性能不均衡;而b+树,完整的数据都是在叶子节点上,其查询效率是固定的。插入、删除操作同样的原理,在b树中,其复杂度明显增加,而b+树相对简单的多。例如,b+树,在插入过程中,只需要通过在每一层搜索一个节点,依次找到节点之后,在节点处插入即可(节点满,则分裂)。

(3)b树中,所有的数据只存储了一份;而b+树,除了存储了所有数据的叶子节点外,还要在内节点存储了键值。所以,在空间占用方面,b+树会比b树多些。

(4)在一个表中,聚族索引占用的空间肯定是最大的,因为它存储了全部数据,而二级索引是建立在某几个经常查询的列上(还有用来“回表”的指针),所以,二级索引的占用空间都会比聚族索引小很多。

索引设计原则

(1)mysql 表主键设计

innodb 以主键排序存储;聚集索引只能是主键;存储所有数据;二级索引包含主键键值。

如果表没有定义主键,会选择第一个唯一索引(非空)作为聚集索引主键。如果唯一索引也没有,mysql后台会自动生成rowid。

字符类型字段最好不要做主键;常见的主键有两种:自增列和uuid。

自增:  顺序存储,索引维护成本低,索引效率高;

uuid:非顺序增长,随机io严重。

(2)索引并不是越多越好,要根据查询,有针对性的创建,考虑在where和order by命令上涉及的列建立索引,可根据explain来查看是使用了索引还是全表扫描;

(3)应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描;

(4)值分布很稀少的字段不适合建索引,例如“性别”这种只有两三个值的字段;

(5)不用外键,由程序保证约束;

(6)尽量不用unique,由程序保证约束;

(7)使用多列索引时主意顺序和查询条件保持一致,同时删除不必要的单列索引。

(8)排序时,排序字段需要注意index, 尤其是关联查询排序时,尽可能使用小表的字段进行排序

sql 优化 原则

(1)避免属性隐试转换 , 如定义moblie varchar  where moblie =198989888会导致全表扫描;

(2)where子句中条件字段本身避免使用函数;

(3)使用获取的必要字段代替select *;

(4)批量插入,使用insert into table (col1,col2,...) values (value1, value2,...),(value1, value2,...); 插入多条数据只有一次提交;

(5)避免使用长事务;

(6)禁止负向查询: not、!=、<>、!<、!>、not in、not like,会导致全表扫描;

(7)大表之间的join,尽量缩小结果集之后再join,否则会消耗较多的内存和cpu;

(8)搜索严禁左模糊或者全模糊(like %xx, 或like %xx%),会导致全表扫描。