Mysql索引

104 阅读2分钟

页的概念

操作系统也存在页这一逻辑单位,磁盘取数据最小的基本单位。

一页 = 16Kb

show GLOBAL STATUS like 'INNODB_page_size';

select 16384/1024;

局部性原理:

  1. 指令1 从0x01取1kb数据到内存 磁盘io 直接取1页
  2. 指令2 从0x02取1kb数据到内存 磁盘io(直接读内存)

索引

INnodb在插入的时候会按照主键进行排序。

create table t1(
a int PRIMARY key,
b int,
c int,
d int,
e VARCHAR(20)
)ENGINE = INNODB;

show index from t1;

insert into t1 values(4,3,1,1,'d');
insert into t1 values(1,1,1,1,'a');
insert into t1 values(8,8,8,8,'h');
insert into t1 values(2,2,2,2,'b');
insert into t1 values(5,2,3,5,'e');
insert into t1 values(3,3,2,2,'c');
insert into t1 values(7,4,5,5,'g');
insert into t1 values(6,6,4,4,'f');

image.png

create index index_t1_bcd on t1(b,c,d); -- 重新建立一颗B+树

image.png

INnodb存储引擎辅助索引存储的是主键,MyIsam存储引擎辅助索引存储的是地址

如果INnodb存储引擎对应的表没有主键,INnodb会自动创建不可见的主键

具体Sql分析

select * from t1 where a = 7; -- a 排序

select * from t1 where b = 1 and c = 1 and d = 1;  -- 走索引

explain select * from t1 where c = 1 and d = 1; -- 不能  最左前缀原则

select * from t1 where b = 1; -- 能

select * from t1 where a > 1; -- 先找a == 1,然后往后找

EXPLAIN select b,c,d,a from t1;  -- 走bcd索引,bcda索引所存储的数据更少,一页可以存储更多数据,这意味着少做几次磁盘io

explain select * from t1 where b = 1 and d = 1;
-- 5.7 之前 索引,回表,过滤
-- 5.7 之后 索引,过滤,回表,索引条件下推,效率高

-- 类型不匹配的时候 字符转化为数字  0-9 转化为对应的 0-9;其他的都是0

select 1='1'; -- 1

select 0='a'; -- 1

select 1='a'; -- 0 

create index idx_t1_e on t1(e); -- B+树

explain select * from t1 where a = 1; -- 1
explain select * from t1 where a = '1'; -- 1 字符转化为数字
explain select * from t1 where e = 1; -- 0
explain select * from t1 where e = '1'; -- 1
explain select * from t1 where a + 1 = 1; -- 0 虽然说理论上 这条sql等价于 explain select * from t1 where a = 1 - 1 但是mysql优化没有做到这一步

select * from t1 where a = 'a'; -- 字符‘a’会自动转换为0