select * from user where name = "jack"
以上sql语句会去name字段上扫描?
因为查询语句条件是:name="jack"
如果name字段上没有添加索引(目录),或者说没有给name字段创建索引,Mysql会进行全扫描,会将name字段上的每一个值都对比一遍,效率比较低。
在查询方面,mysql主要2种方式:
(1)全表扫描。
(2)根据索引检索。
索引实现原理
提醒1:一个字段上,如果有unique约束的话,也会自动创建索引。
提醒2:在任何数据库中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号,如下:
提醒3:在mysql中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MyIsam存储引擎中,索引存在一个.myi文件中;在innoDB存储引擎中,索引存储在一个逻辑名称叫tablespace当中。不管索引存储在哪里,索引在mysql当中都是以一个树的形式存在的。
大致实现原理:
索引的实现原理就是缩小扫描的范围,避免全表扫描。
什么条件下使用索引?
条件1:数据量庞大(到底多么庞大,这个需要测试,因为每一个硬件设备不同)。
条件2:该字段经常出现在where后边,以条件的形式存在,也就是这个字段经常被扫描。
条件3:该字段很少DML(增删改)操作。(因为DML之后,索引需要重新排序)。
注意:
不要随意的添加索引,因为索引也需要维护的,太多的话,反而会降低系统的性能。
建议通过主键查询,建议通过unique约束的字段进行查询,效率是比较高的。
操作,如何添加索引?
-- 给emp表的ename字段添加索引,起名:emp_ename_index
create index emp_ename_index on emp(ename)
删除索引?
-- 将emp表上的 emp_ename_index 索引对象删除
drop index emp_ename_index on emp
在mysql中,查看一个sql语句是否使用的索引?
使用explain
explain SELECT * FROM `sd_device_info` where school_id = 216
下边sql没有使用索引,因为type是all
索引失效情况?
select * from emp where ename like '%L'
情况一:
ename字段上即使加了索引,也不会走索引?
原因:因为模糊匹配当中是以 "%"开头的。尽量避免模糊查询的时候,以"%"开始。
情况二:
情况三:
补充(2022-03-02):
情况四:
列字段类型 与 where 条件查询字段值类型不一样,如下:
a表,字符串 a_age 加了索引
下边where a_age = 20 ,a_age 字段类型是字符串,但是条件是数字,导致索引失效。
EXPLAIN select a_name,a_age from a where a_age =20
情况五:
尽量用 left join 后边的表作为查询条件
主表作为条件,left join 右侧的表会失效!
关于 explain
使用explain前,必须先执行下sql语句,然后在使用,如果直接使用explain 结果会有偏差,如下:
索引的分类
单一索引:一个字段上添加索引。
复合索引:两个字段或者更多字段上添加索引。
主键索引:逐渐上添加索引。
唯一性索引:具有unique约束的字段上添加索引。