1.索引:
索引是对数据库表中的一列或多列的值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息。
B+tree:所有数据都保存在叶子结点中,双向链表结构,速度比b-tree快
b-tree:所有里子结点都出现在同一层,叶子结点不包含任何关键字的信息
聚集索引和普通索引(B+tree)
普通索引(非聚集索引):创建方法:
alter table table_name add index index_name(索引字段)
create index index_name on table_name(索引字段)
查看执行计划:explain select * from table_name where name=’table_name_col’
(1)先看查询类型type:出现all表示全表扫描
(2)再看key列,null表示没有使用索引
(3)然后看rows列,表示sql在执行过程中被扫描的行数,数值越大,意味需要扫描的行数越多,耗时长
(4)最后看extra列,是否有Using filesort或Using temporary,性能差;表示返回结果的行占需要读到的行的百分比。
2.SQL语句优化思路:
(1)先看表的数据类型是否设计合理,有没有遵守选取数据类型越简单越小的原则
(2)表中的碎片是否整理
(3)表的统计信息是否收集,只有统计信息正确,执行计划才可以帮助我们优化SQL
(4)查看执行计划,检查索引的使用情况,没有索引,创建索引
(5)创建索引前,查看索引的选择性,判断这个字段是否合适创建索引(主键索引和唯一索引的选择必是1)
(6)创建索引后,再看执行计划,对比结果
合理创建索引的建议:
(1)经常被查询的列(一般放在where条件后面)
(2)经常用于表连接的列
(3)经常排序分组的列(order by 或者 group by后面的字段)
例,test表给name字段创建索引,看索引选择性:select count(distinct name)/count(*) from test;
0.8表示重复值少,选择性高,非常适合创建索引
create index idx_01 on test(name);
explain select * from test where name=’name’;
普通索引获取数据方式:先通过索引页的叶子节点找到对就主键,再通过主键找到相对应的行数数据记录,若一张表中对某一个字段创建一个普通索引,但这个字段有重复值,那么此字段做where条件时,每次取到的主键值可能不是按顺序的,那么随机I/O行为就会发生。
3.ICP\MRR\BKA:
ICP:通过optimizer_switch参数中的index_condition_pushdown选项来控制,默认为on
show variables like '%optimizer_switch%'\G;
set optimizer_switch=”index_condition_pushdown=on|off”;
当使用ICP优化时,执行计划的extra列会显示Using index condition关键字提示
MRR:Multi-Range Read optimization ; 5.6之后才有,通过optimizer_switch参数中mrr和mrr_cost_based控制。默认参数开启
Set gloabal optimizer_switch=’mrr=on|off,mrr_cost_based=on|off’;
当mrr=on、mrr_cost_based=on时,表示以cost_base方式还选择启用MRR优化,当发现优化后的代价过高时就会不使用此项优化。
当mrr=on,mrr_cost_based=off时,表示总是开启MRR优化。
当使用MRR优化时,执行计划的extra列会显示Using关键字提示。
生产环境中,read_rnd_buffer_size的值可在4-8M之前调整。
BKA:batched key access ,提高表join性能算法。Optimizer_switch参数中batched_key_access选项控制,默认关闭。
开启参数,必须先要保证是在强制使用MRR基础上才可以:
SET global optimizer_switch=’mrr=on,mrr_cost_based=off’;
SET global optimizer_switch=batched_key_access=on’;
4.主键索引和唯一索引:
主键索引:就是聚集索引,每张表中有且仅有一个主键,可以由表中一个或多个字段组成。
主键条件(1).主键必须唯一,不能包含null值,一定要保证该值是自增属性。使用自增列做主键,可以保证写入数据的顺序也是自增,提高 了存取效率。
Alter table table_name add primary key(column);
唯一索引是约束条件的一种,不允许有重复值,但是可有nul值,唯一索引可有多个:
Alter table table_name add unique(column);
覆盖索引:
不能写select * ,需要具体的列,select id from test where name=’namexx’\G;
前缀索引:不能在order by或group by中使用,对于blob,text或都很长的varchar类型列,为它们的前几个字符建立索引。
alter table table_name add key (column_name(prefix_length));
prefix_length需要根据实际表的内容来选择
联合索引:也叫复合索引,在表中两个或两个以上列创建的索引,满足最左前缀原则,一般把选择性高的列放在前面。
create index idx_c1_c2 on t (c1,c2);
多列建议使用union 不使用or
哈希索引:只能进行等值查询,不能排序,模糊查找,范围查询;查询时不需要 像b+tree从根到叶子结点查询。
5.索引优点:
- 提高数据检索效率
- 提高聚合函数效率
- 提高排序效率
- 使用覆盖索引可以避免回表
6.索引创建四个不要:
- 选择性低的字段不要创建索引(例如,性别,状态等)
- 很少查询的列不要创建索引(项目开始就确定)
- 大数据类型字段不要创建索引
- 尽量不使用null,应该指定列为not null,mysql中含null列很难优化,使用空字符串代替空值
7.使用不到索引的情况:
- 索引扫描的行记录超过全表的30%,优化器不走索引
- 联合索引中,第一个查询条件不是最左索引列
- 联合索引中,第一个索引列使用范围查询,只能使用部分索引,有ICP出现(范围查询是指<、= 、<=、between and )
- 联合索引中,第一个查询条件不是最左前缀列
- 模糊查询条件列最左以通配符%开始(可以考虑放到子查询里)
- 两个单列索引,一个用于检索,一个排序,只能使用到一个索引,可以建立联合索引
- 查询字段上面有索引,但是使用了函数运算。