文章目录

  • 从一个示例开始
  • 离散性
  • 联合索引
  • 最左匹配原则
  • 三星索引(索引设计尽量遵循该原则)


从一个示例开始

例如,此处有一个User表,表的字段及类型如下表所示:

字段

类型

id

int

name

varchar(32)

age

int

gender

tinyint

mobile

varchar(20)

假设创建单列索引,以哪列作为索引比较合适?

离散性

count distinct col :count col

即当前列去除重复的数据的个数:当前列的总数,该值越大代表离散性越好。

举个例子,如果在gender列上面创建索引,由于gender性别只有男和女两种,例如这里1表示男2表示女,那么即使创建了索引,它也会走全表扫描:

mysql建表性别为男或女 mysql 性别建立索引_mysql建表性别为男或女


也就是说,此处选择姓名创建索引是最好的选择(离散性的比值为1:10已经是一个比较好的索引了 )。

联合索引

如果有一个联合索引(name,mobile,age),可以理解为创建了三个索引即(name)(name,mobile)(name,mobile,age)

最左匹配原则

mysql建表性别为男或女 mysql 性别建立索引_索引_02

对于mysql来说,建立的复合索引是通过从左到右的顺序去建立搜索树的。那么去检索时,例如查询条件为name=‘Young’ and mobile=‘155555’,age=‘26’,则会先优先比较name去确定下一步的搜索因子,此处因为查询了手机号码,索引会比较下一个搜索因子手机号码,然后是age这个搜索因子,最后得到数据返回。举一反三,若查询语句中没有name,则这次查询不会走索引; 如果使用name和age进行查询,则由于缺失了mobile这个因子导致name走索引,而age条件查询需要一一进行比较。

例如上表创建联合索引:(name,mobile,age)

(1)select * from user where name = ‘Young’ and mobile like ‘155%’ and age=26; (2列用到索引)
(2)select * from user where age=26 and name = ‘Young’;(1列用到索引)

mysql建表性别为男或女 mysql 性别建立索引_mysql_03


答案是4。

上篇文章可知,所有的非主键索引都是稀疏索引,第四条查询会先联合索引name,phoneNum取到的name,phoneNum和id的值,不需要再次遍历主键的索引树,效率最高。(也叫覆盖索引)

三星索引(索引设计尽量遵循该原则)

第一颗:where后面匹配的索引关键字列越多越好,扫描的数据越精确,越少越好。–通过索引筛选出的数据越少越好(列的离散性)

第二颗:避免再次排序(例如上篇文章讲到的id自增天然有序,则使用order by的时候无需在内存中进行二次排序)

第三颗:尽可能的应用覆盖索引,减少回表操作。