Mysql 进阶学习Ⅰ
之前学习的数据库知识,主要是对表的增删改查(CRUD),并没有考虑对数据库做出优化,这章内容就是学习怎么优化数据库。
- 为什么要优化数据库?
当数据库中的数据大于50W的时候,我们在操作数据时,有没有做过优化就会产生比较大的影响,特别是千万级,亿级数据库,优化就显的尤为重要。 - 知识回顾
-
人写sql语句顺序
select * from
join on
where
group by
having
order by
limit -
机器执行sql语句顺序
from
join on
where
group by
having
select
order by
limit -
sql解析图示
索引优化
什么是索引?
Mysql官方定义:索引(Index)是帮助Mysql高效获取数据的数据结构。
-
一般来说索引本身很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上,我们平常所说的索引,如果没有特别指明,都是指B树结构组织的索引。在磁盘上表现为后缀.MYI(mysql index的缩写)的文件。
-
一般建立索引的列不超过6-7个,太多会影响整个Mysql引擎性能。
一. Mysql索引结构
- BTREE:B树(Balance Tree多路平衡查找树)
- 其他不常用的:
- Hash索引
- full-text全文索引
- R-Tree索引
二. 索引的分类
- 单值索引:即一个索引只包含单个列,一个表可以有多个单列索引。
- 唯一索引:索引列的值必须唯一,但允许有空值。
- 复合索引:一个索引包含多个列。
- 使用工具可以很方便的建立索引,如Navicat。
三. 关键字EXPLAIN
使用EXPLAIN关键字可以模拟执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句,分析你的查询语句或是表结构的性能瓶颈。
-
1、EXPLAIN作用:
- 查看表的读取顺序查看
- 查看数据读取操作的操作类型
- 查看哪些索引可以使用
- 查看哪些索引被实际使用
- 表之间的引用
- 每张表有多行被优化器查询
-
使用方法:
- Explain+SQL语句
- 执行计划包含的信息如下图:
-
2、EXPLAIN性能指标参数详解
-
id:说明每张表的执行顺序,id越大执行越早,id越小执行越晚,id一样按照顺序从上往下执行。
-
select_type:查询类型,主要用于区别普通查询 ,联合查询,子查询等复杂查询。
- 查询类型分为:
-
SIMPLE,简单查询,查询中不包含子查询或者UNION
-
PRIMARY,主键查询
-
SUBQUERY,子查询
-
DERIVED,衍生表,在from列表中包含的子查询被标记为DERIVED,Mysql会递归执行这些子查询,把结果放到临时表里。
-
UNION,联合查询
-
UNION RESULT,
-
table:查询的是哪张表
-
type(重点):查询时使用的类型(使用的索引类型),性能从快到慢依次为,system>const>eq_ref>ref>range>index>ALL。一般来说,查询至少保证range级别,最好能到ref。
- 索引级别类型分为:
- system,系统常量,只有一条记录
- const,常量,例如:查询条件是一个具体的值。where age = 20(该字段必须已经建立索引)
- eq_ref(特殊关联索引),唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。例如:select * from m ,e where m.num = e.pid,m表中只有一条数据,e表中的pid是索引键
- ref(关联索引),非唯一性索引扫描,多表查询时尽量关联到索引,基本都能达到这个级别
- range(范围索引),例如:select * from m where m.id < 10
- index(Full Index Scan),用到了索引,只遍历索引树
- ALL(Full Table Scan),全表查询,没有用到索引
- 复合索引中字段的位置会影响索引的类型 ,复合索引在建立时和使用时,,尽量考虑在用户应用查询时,常用的排序方向和字段组合顺序。
-
possible_keys:可能用到的索引
-
key:实际使用的索引
-
key_len:索引字段的最大可能长度。建库时varchar长度不要太长,影响效率。常见字段类型的key_len:
int:4
varchar:长度 * 3+2(var自身可变长度)+1(运行null值)
char:长度 * 3+1(运行null值) -
ref:关联的索引字段是哪个
-
rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录需要读取的行数
-
Extra:额外信息
- Using filesort,避免出现的信息,说明排序没有充分利用索引
- Using temporary,避免出现的信息,说明分组没有充分利用索引
- Using index,使用索引
- Using where,
- using join buffer,
- impossible where,
-
-
3、索引失效
- 所有索引字段全部匹配速度最快。
- 如果索引有多列,查询从索引最左前列开始并且不跳过索引中间列。
- 不在索引列上做任何操作(计算、函数、类型转换),会导致索引失效转而全表扫描。
- 索引中范围(>、<等)条件右边的列全失效。
- 尽量使用覆盖索引(只访问索引列的查询),减少select*。
- 使用不等于(!=或<>)时,会导致索引失效。
- null/not null 对索引有影响。
- like以通配符(%)开头,会导致索引失效。
- 字符串不加单引号,会导致索引失效。
- 尽量不要用or, 会导致索引失效。