mysql索引

创建最佳实践

主键索引名为pk字段名;唯一索引名为uk字段名;普通索引名则为idx字段名。

pk 即primary key;uk 即 unique key;idx 即index的简称。索引名称是表内唯一即可

MyISAM VS Innodb

内容 MyISAM Innodb
叶子节点存放数据 数据记录的地址 完整的数据记录
索引与数据文件 合一 分索引文件,数据文件

索引:

创建数量限制:

  • 单表不超过5个(浪费空间,更新变慢)
  • 区分度低的字段,例如性别,不要建索引。(离散度太低,导致扫描行数过多)
  • 频繁更新的值,不要作为主键或者索引。(——页分裂)
  • 不建议用无序的值(例如身份证、UUID )作为索引

加索引字段

  • 在用于 where 判断 order 排序和 join 的(on)字段上创建索引

创建组合索引的顺序:

  • 区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数)
  • 尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO 性能也就越好)
  • 使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)

  • 尽可能把所有列定义为 NOT NULL
  • 单表记录数量控制在500万以内
  • 尽量做到冷热数据分离,减小表的宽度
  • 禁止在数据库中存储图片,文件等大的二进制数据
  • 不建议使用过长的字段作为主键

外键

会影响父表和子表的写操作从而降低性能

表与表之间的关联键上建立索引

过长的字段,使用前缀匹配方式创建索引

查询

原则

  • 最左前缀匹配原则
  • 索引列不能参与计算
  • 关联查询表,建议不超过 5 个

具体查询

  • 在明显不会有重复值时使用 UNION ALL 而不是 UNION
  • 少使用子查询(原因:子查询的结果集无法使用索引)

or-> in

优化:
充分利用已有索引,尽可能的扩展索引
覆盖索引(不需要回表)
范围查询放在最右边

Mysql如何为表字段添加索引???

1.添加PRIMARY KEY(主键索引)

ALTER TABLE table_name ADD PRIMARY KEY ( column )
2.添加UNIQUE(唯一索引)

ALTER TABLE table_name ADD UNIQUE ( column )
3.添加INDEX(普通索引)

ALTER TABLE table_name ADD INDEX index_name ( column )
4.添加FULLTEXT(全文索引)

ALTER TABLE table_name ADD FULLTEXT ( column)
5.添加多列索引

ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )

索引结构 B+树

叶子结点放数据,树节点只包含索引,减少IO次数
叶子节点间有指针相连,遍历叶子就可以区间访问

列值为NULL时,查询是否会用到索引?

MySQL 中存在 NULL 值的列也是走索引的
计划对列进行索引,应尽量避免把它设置为可空,因为这会让 MySQL 难以优化引用了可空列的查询,同时增加了引擎的复杂度

说一些索引失效的情况
  • 如果条件中有 or,即使其中有部分条件是索引字段,也不会使用索引
  • 复合索引,查询条件不使用索引前面的字段,后续字段也将无法使用索引
  • 以 % 开头的 like 查询
  • 索引列的数据类型存在隐形转换
  • where 子句里对索引列有数学运算
  • where 子句里对索引列使用函数
  • MySQL 引擎估算使用全表扫描要比使用索引快,则不使用索引