select *from user where username = 'a' and password = 'b'
如果useranme和password都是普通索引,那么他们会把2个索引都查出来,然后在把他们的交集拿出来
如果username是唯一索引,password是普通索引,那么我们的mysql就会优先使用唯一索引
select * from user where a > 2 and b =3
a和b都是索引,而且还是联合索引
这个时候索引b会失效,因为使用索引a然后在通过回表找里面的b是否等于3
因为联合索引的机制是先从做到有,这个操作在a索引中,他收到的任务是找到所有>2的数据,当大于2的数据都找出来了,那么此时的B是无序的,所以就导致了索引失效,索引不失效的前提的是索引必须保持有序。
虽然会索引失效,但是在Mysql新版本会使用索引下推的优化
select * from user a >= 2 and b = 3
这时候a和b索引就不会失效,因为a收到的命令是找到>=2的数据,当找到了2以后,然后就去看b,在2内的b索引是有序的,所以这时候b的索引是可以生效的。
ELECT * FROM t_table WHERE a BETWEEN 2 AND 8 AND b = 2
这个是和我们>= 是一样的,<=一样的不会导致我们的2个索引失效。不同的数据库会有差异,Mysql是这样的
SELECT * FROM t_user WHERE name like 'j%' and age = 22
name和age他们也是联合索引。首先会找到所有j开头的单词,然后,在挨个判断age是否等于22,也就是age索引会失效。
如果他们都是普通索引,那么mysql会根据索引的复杂度或者索引的大小,唯一值值数量 和 选择性(如j开头的数据比较少) 和索引长度大小(比如值int就是4个字节,varchar(20)就是20个字节)等去选择一个合适的索引去使用
Mysql在使用> <范围查询的时候会导致索引失效,但是在使用前缀匹配的范围不会失效如<= >= betwwen like等
字段有一些唯一性,比如username,需要使用where快速定位的。经常用group by和order by的,因为索引都是排序好的就不需要在排序一次了。
where 和group by、 order by用不到的字段,因为索引的价值是快速定位。
当字段有大量重复内容是不需要加索引的。Mysql有一个优化,如果一个字段的内容重复率比较高,那么就会全表扫描。
经常更新的字段不需要建立索引
表数据太少的时候不需要建立索引。
select * from order where status = 1 order by create_time desc
这种情况要给status和create_time建立一个联合索引,这样只用到status索引还要对我们的time排序,这样就会using filesoft,这样根据status筛选出来的就是按照time排好序的,避免了在文件排序
? 使用某个字段的前几个字符建立索引,优点就是减少索引大小,比较适合大字段作为索引的情况,缺点是group by无法利用这个前置索引,无法把前置索引作为覆盖索引。
? 就是我们要查出来的内容就是我们的索引的内容,比如我们联合查询(a,b,c)然后我们
select a,b,c from tables where a =12
这个时候我们就避免了一个回表找内存的操作,叶子节点直接找到了我们想要的数据。
如果我们主键是自增,每次插入数据都是追加操作,不需要重新移动数据。
如果非自增主键,我们每次插入的位置是不确定, 可能被插入了某个数据页的中间,这就不得不从启动其他数据到别的页来满足这个插入需求了,会导致页分裂,页分裂可能会导致大量的内存碎片,导致索引结构不紧密,影响查询效率。
比如当前有一个页[1,2,4,5],这时候我们要插一个3这时候就可能[1,2,null,null,null],[3,4,5,null,null] 导致了页分裂
第一个原因,因为如果索引列为NULL,会导致优化器使用索引的时候更加复杂,更加难优化。因为NULL会列会使索引、索引统计和值比较都比较困难。在使用索引统计个数的时候,如果为null,会不作为个数相加。比较困难因为在null在sql中都是unkwon的。
tip:NULL一共有3种状态,真、假和未知
Key_len只是告诉你索引查询使用了哪些字段,而不是这个字段具体占了多少字节空间
其中的type
all是全表扫描
index是全索引扫描
range是索引范围扫描
ref是非唯一索引
eq_ref是唯一索引扫描
const 只有一条扫描索引,或者唯一扫描索引
B+Tree的叶子结点用双向链表连接起来,适合范围查找(B Tree无法做到这点)
B+Tree的高度很低,及时在千万级别的数据量下,依然维持到3-4层,也就是说一次查询只需要做3-4次io就可以找到目标数据
使用左模糊%xx 或者左右模糊%xx%
使用计算、函数、类型转换。
使用or