索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据量非常大的时候,可以先通过索引表找到该行数据对应的物理地址然后访问相应的数据(可以把索引想象成书的目录,可以根据目录中的页码快速找到所需的内容)
优点:
缺点:
不用select * 查询,仅查询需要的字段值
尽量不使用like、in等无法走索引的关键字
正确使用索引,对常用的字段,如where关键字或order by关键字后的字段加索引
如果数据量很大,建议分库分表
使用缓存,如redis存入热点数据
create table 表名 (..., primary key(字段名));
alter table 表名 add primary key(字段名);
create table 表名 (..., unique index 索引名(字段名));
alter table 表名 add unique index 索引名(字段名));
create table 表名 (..., index 索引名(字段名));
alter table 表名 add index 索引名(字段名));
create table 表名 (..., fulltext key 索引名(字段名));
alter table 表名 add fulltext index 索引名(字段名));
create table 表名 (..., index 索引名(col1, col2, col3));
alter table 表名 add index 索引名(col1, col2, col3));
组合索引中列的值为null,组合索引就会失效
like操作中,‘%路飞%’ 索引会失效,但是’路飞%’就不会失效(分情况)
使用表达式或者函数索引会失效,例如:select * from user_info where year(gmt_modified) < 2021
,这将导致索引失效而进行全表扫描,因此我们可以改成:gmt_modified<’2021-01-01′
查询条件中 < 符号,> 符号和 != 会导致索引失效,如果对主键索引使用 != 则不会失效,对主键索引或者整数类型的索引使用 < 符号或者 > 符号索引也不会失效
查询条件中使用is null或者is not null会导致索引失效
字符串不加单引号会导致索引失效
在查询条件中使用OR连接多个条件会导致索引失效,除非OR连接的每个条件都加上索引
explain关键字可以模拟执行SQL查询语句,分析SQL查询语句性能,查看SQL可以优化的地方,例如:
explain列的含义:
id(查询序列号):相同,执行顺序由上到下;不同,如果时子查询,id序号递增,id越大执行的优先级越高
select_type(查询类型):表示select的类型。
table(表名或者别名):输出结果集的表
type(访问类型):从左到右,性能由最差到最好,ALL(全表扫描)
possible_keys(可能用到的索引):查询中可能用到的索引
key(实际用到的索引):查询中实际用到的索引
key_len(索引长度):索引的长度
ref(与索引比较的列):显示之前的表在key列记录的索引中查找值所用的列或者常量
rows(估算的行数):扫描的行数
filtered(按表条件筛选的行百分比):列针对表中符合某个条件(where子句或者联接条件)的记录数的百分比所做的一个悲观估算
Extra(额外信息):
using filesort:说明mysql无法利用索引进行排序,只能利用排序算法进行排序,会消耗额外的位置
using temporary:建立临时表来保存中间结果,查询完成之后把临时表删除
using index:这个表示当前的查询是覆盖索引的,直接从索引中读取数据,而不用访问数据表。如果同时出现using where 表名索引被用来执行索引键值的查找,如果没有,表面索引被用来读取数据,而不是真的查找
using where:使用where进行条件过滤
using join buffer:使用连接缓存
impossible where:where语句的结果总是false