MySQL优化之索引基础,实战优化的基础知识

数据库设计总结

1.尽量避免过度设计,例如会导致及其复杂查询的schema设计,或者有很多列的表设计。
2.使用小而简单的合适数据类型,除非真实数据模型中有确切的需要,否则应该尽可能地避免使用NULL值。
3.尽量使用相同的数据类型存储相似或相关的值,尤其是需要在关联条件中使用的列。
4.注意可变长字符串,其在临时表和排序时可能导致悲观的按最大长度分配内存。
5.尽量使用整形定义标识列。
6.避免使用MySQL已经废弃的特性,例如指定浮点数的精度等。
7.小心使用ENUM和SET。虽然他们用起来很方便,但是不要滥用,否则有可能变成陷阱。

索引

BTree索引,是一种树结构,索引速度比全表查询速度快。
每个叶子节点即使MySQL中的一个页,默认每页16KB大小。
MySQL中InnoDB使用B+Tree,B+Tree中每个叶子节点都有一个指向先一个叶子节点的指针。

组合索引

InnoDB中BTree索引生效的情况【customer创建组合索引(last_name, first_name, email)】
匹配最左前缀:查找姓为MILLER的人,只使用索引的第一列。
explain select * from customer where last_name='MILLER';
全值匹配:全值匹配是指和索引中所有的列进行匹配,例如查找姓名为MARIA MILLER,email为[email protected]的人。
explain select * from customer where last_name='MILLER' and first_name='MARIA' and email='[email protected]';
匹配列前缀:可以匹配某一列值的开头部分,例如查找以M开头的姓的人。
EXPLAIN select * from customer where last_name like 'M%';
匹配范围值:查找姓大于等于WEINER的人。
EXPLAIN select * from customer where last_name>='WEINER';
精确匹配某一列并范围匹配另一列:查找所有姓为MILLER,且名字是字母M开头的人。即第一列last_name的全匹配,第二列first_name范围匹配。(也是前缀匹配)
EXPLAIN select * from customer where last_name='MILLER' and first_name like 'M%';

#如果不是按照索引的最左列开始查找,则无法使用索引【不从last_name列开始检索】
explain select * from customer where first_name='MARIA'  and email='[email protected]';
#不能跳过索引中的列【没有first_name列】
explain select * from customer where last_name='MILLER' and email>'[email protected]';
#如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找【first_name为范围查找,email列无效】
explain select * from customer where last_name='MILLER' and first_name>'MARIA'
                                       and email='[email protected]';
Hash索引,在MySQL中只有Memory引擎支持

当Hash索引中出现哈希冲突的时候,存储引擎需要遍历链表中所有的行,找到所有符合条件的数据。
冲突越多,索引代价越大。
<=> 并非 <>
Mysql 的 InnoDB引擎 有一个功能叫做“自适应哈希索引”。当MySQL发现某些索引值被频繁使用时,会在内存中基于BTree索引创建一个哈希索引。整个过程无法认为控制,仅可以通过innodb_adaptive_hash_index属性配置是否开启,默认开启该功能。

InnoDB聚簇索引(主键索引)

已满的页中,如果需要插入新的数据,会导致页分裂
InnoDB二级索引



Select id,name from tablename where name=’Rose’; #只需要遍历二级索引即可得到结果。

Myisam引擎索引

Myisam引擎中,主键索引与其他索引在结构上没有区别。

InnoDB中默认最大填充因子是页的15/16大小 MySQL默认每页16K 数据达到15K的时候, 分配到下一页。 不同页之间可能不是顺序的,只是通过一个指针相连。

InnoDB主键最好是连续递增的值,尽量避免使用UUID之类的长而无需的字符串。使用UUID做主键,在BTree的聚簇索引上,会导致插入速度慢,索引空间更大,其他二级索引空间也会更大。
索引空间变大的原因有两个,一个是由于主键字段更长,其次是因为页分裂和碎片(页不饱和)导致。

索引列的字段要尽可能小 因为BTree索引树高度页的大小以及页里面的数据大小决定的。数据越小,磁盘块存储的数据越多,树的高度越低,查询性能越高。

三星索引:

1、索引将相关的记录放到一起(Where子句后面的条件都可以使用索引,体现组合索引的利用)
2、索引中数据的顺序和查找中的排列顺序一致(利用索引的有序性直接得到排序结果)
3、索引中的列包含了查询中全部需要的列(利用索引中的值,直接得到查询结果,避免回表)

你可能感兴趣的:(MySQL优化之索引基础,实战优化的基础知识)