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.索引优点:

  1. 提高数据检索效率
  2. 提高聚合函数效率
  3. 提高排序效率
  4. 使用覆盖索引可以避免回表

 

6.索引创建四个不要:

  1. 选择性低的字段不要创建索引(例如,性别,状态等)
  2. 很少查询的列不要创建索引(项目开始就确定)
  3. 大数据类型字段不要创建索引
  4. 尽量不使用null,应该指定列为not null,mysql中含null列很难优化,使用空字符串代替空值

 

7.使用不到索引的情况:

  1. 索引扫描的行记录超过全表的30%,优化器不走索引
  2. 联合索引中,第一个查询条件不是最左索引列
  3. 联合索引中,第一个索引列使用范围查询,只能使用部分索引,有ICP出现(范围查询是指<、= 、<=、between and )
  4. 联合索引中,第一个查询条件不是最左前缀列
  5. 模糊查询条件列最左以通配符%开始(可以考虑放到子查询里)
  6. 两个单列索引,一个用于检索,一个排序,只能使用到一个索引,可以建立联合索引
  7. 查询字段上面有索引,但是使用了函数运算。