比较乱,暂时笔记,【点进来的没有必要看】
B+ 树这种索引结构,可以利用索引的“最左前缀”,来定位记录。
第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
那些不符合最左前缀的部分,会怎么样呢?
而 MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
对于普通索引来说,查找到满足条件的第一个记录 (5,500) 后,需要查找下一个记录,直到碰到第一个不满足 k=5 条件的记录。对于唯一索引来说,由于索引定义了唯一性,查找到第一个满足条件的记录后,就会停止继续检索。
而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。当然,扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。
MySQL 在真正开始执行语句之前,并不能精确地知道满足这个条件的记录有多少条,而只能根据统计信息来估算记录数。这个统计信息就是索引的“区分度”。显然,一个索引上不同的值越多,这个索引的区分度就越好。而一个索引上不同的值的个数,我们称之为“基数”(cardinality)。也就是说,这个基数越大,索引的区分度越好。
analyze table t 命令,可以用来重新统计索引信息。
MySQL 是支持前缀索引的,也就是说,你可以定义字符串的一部分作为索引。alter table SUser add index index2(email(6));使用前缀索引后,可能会导致查询语句读数据的次数变多。使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本。
我们在建立索引时关注的是区分度,区分度越高越好。因为区分度越高,意味着重复的键值越少。
按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(),所以我建议你,尽量使用 count()。