创建最佳实践
主键索引名为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 引擎估算使用全表扫描要比使用索引快,则不使用索引