首先我们还是先把表结构说下:用户表tb_user结构如下:
1、 不要在索引列上进行运算 *** 作, 索引将失效。
手机号phone字段有唯一索引,当根据phone字段进行函数运算 *** 作之后,索引失效:
2、 字符串类型字段使用时,不加引号,索引将失效。
如果字符串不加单引号,对于查询结果,没什么影响,但是数 据库存在隐式类型转换,索引将失效。
3、 如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。
接下来,我们来看一下这三条SQL语句的执行效果,查看一下其执行计划:
由于下面查询语句中,都是根据profession(专业)字段查询,profession字段是一个普通的索引, 我们主要看一下,模糊查询时,%加在关键字之前,和加在关键字之后的影响。
经过上述的测试,我们发现,在like模糊查询中,在关键字后面加%,索引可以生效。而如果在关键字 前面加了%,索引将会失效。
4、 用or分割开的条件, 如果or前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会 被用到。
由于age没有索引,所以即使id有索引,索引也会失效。所以需要针对于age也要建立索引。
5、 数据分布影响:如果MySQL评估使用索引比全表更慢,则不使用索引。
索引并不是时时都会生效的,比如以下几种情况,将导致索引失效:
1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
2.对于多列索引,不是使用的第一部分,则不会使用索引
3.like查询是以%开头
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
此外,查看索引的使用情况
show status like ‘Handler_read%'
大家可以注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
handler_read_rnd_next:这个值越高,说明查询低效。
------------------
1、WHERE字句的查询条件里有不等于号(WHERE column!=...),MYSQL将无法使用索引
2、类似地,如果WHERE字句的查询条件里使用了函数(如:WHERE DAY(column)=...),MYSQL将无法使用索引
3、在JOIN *** 作中(需要从多个数据表提取数据时),MYSQL只有在主键和外键的数据类型相同时才能使用索引,否则即使建立了
索引也不会使用
4、如果WHERE子句的查询条件里使用了比较 *** 作符LIKE和REGEXP,MYSQL只有在搜索模板的第一个字符不是通配符的情况下才能
使用索引。比如说,如果查询条件是LIKE 'abc%',MYSQL将使用索引;如果条件是LIKE '%abc',MYSQL将不使用索引。
5、在ORDER BY *** 作中,MYSQL只有在排序条件不是一个查询条件表达式的情况下才使用索引。尽管如此,在涉及多个数据表的查
询里,即使有索引可用,那些索引在加快ORDER BY *** 作方面也没什么作用。
6、如果某个数据列里包含着许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含了净是
些诸如“0/1”或“Y/N”等值,就没有必要为它创建一个索引。
1.索引失效的原因联合索引排序的原理:先对第一个字段进行排序,在第一个字段相同的情况下考虑第二个字段,然后在第二个字段相同的情况下才考虑第三个字段...
CREATE TABLE 'test_user'(
'id' int(11) not null auto_increment comment '主键id',
‘user_id’ varchar(36) not null comment '用户id',
'phone' varchar(20) not null comment '用户名称',
'lan_id' int(9) not null comment '本地网',
'region_id' int(9) not null comment '区域'
)ENGINE=InnoDB Auto_increment=4057960 Default charset=utf8mb4
假设将('phone', 'lan_id', 'region_id')组成的联合索引
Explain select * from test_user where lan_id = 1
此时的索引是失效的,因为联合索引是遵循最左前缀法则即第一个字段有序的情况下lan_id才有序。现在是跳过phone,直接搜索lan_id相当于在一个无序的B+树上搜索,所以只能全表扫描。
例1下例范围查找的右边索引会失效
Explain select * from test_user where a >1 and b = 1
为什么索引会失效?
因为我们可以找到a >1的所有的节点,但是此时的b索引是无序的,仍然不可以通过二分查找法来查找
例2. like查询中,如果%放在两边或者放到左边,它都是不走索引的。只有%放到右边,它某些情况才会走这个索引。这是什么原因?
字符串在B+树里面存储的时候,它也是按照字母的大小去排序。首先按照第一个字母去比较,如果第一个字母相同则按照第二个字母去比较和最佳左前缀法则相似。如果左边用了%,那后面的字符是无序的,此时就不能使用二分查找来定位元素还是退化为了全表扫描。
3.Mysql中的索引查询为什么使用了B+树结构,而不使用哈希索引或者B树?
首先哈希值是无序的,不能够进行范围查找。
平衡二叉树的缺点是当数据量非常大的时候,其深度也会非常深这样也会导致查找效率慢。其次其存在回旋查找的问题。比如说当存在范围查询>5的时候定位到该元素之后还得回溯到前面的节点元素6,7
B树的最大特点是一个节点可以存储多个值,这样可以使得树的高度变矮,从而使得树的查找速度变快。但是其也存在回旋查找的问题。
B+树则解决了这个问题,它的非叶子节点存储的是key,其叶子节点既存储了key也存储了value并且其叶子节点是有序的,节点之间用指针相连也正是因为这一点使得B+树在范围查询的时候不存在回旋问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)