mysql 索引

1.索引

B*Tree索引 

b-tree -> b+tree(建立叶节点的双向连接) -> b*tree (建立叶节点和枝节点的双向连接)

聚簇索引B*tree 结构(Innodb独有)

簇?

区 extent ====>簇===>64个pages ===》1M

作用:有了聚簇索引之后,将来插入的数据行,在同一个区内,都会按照id值得顺序,有序的存储在磁盘上。

mysql innodb表 聚簇索引组织存储数据表

构建前提:

建表时:指定了主键列,mysql innodb会将主键作为聚簇索引列

没有指定主键,自动选择唯一(unique)的列,作为聚簇索引

以上都没有,生成隐藏聚簇索引

画图说明聚簇索引  


辅助索引btree结构:

说明:使用普通列作为条件构建的索引,需要认为创建

作用:非聚簇索引列之外的查询条件的优化

图解


辅助索引一般需要回表,也就是回到聚簇索引进行查询.

辅助索引分类:

单列索引:name

联合索引:

使用多列构建同一个索引

联合索引,注意最左原则 idx(a,b,c)

查询条件中,必须包含最左列 ,也就是a列

建立联合索引时,一定要选择重复值最少的列,作为最左列,

这样能筛选到最少的数据页.

全部覆盖:

select * from t1 where a =  and b= and c = 

select *from t1 where a= 

select *from t1 where a= and c =  c的索引不能走

select * from t1 where a=  and b > < >= <= like and c =   由于b出现了不等值的情况,

所以c的所以也不能走  

select xxx from t1 where  b order by a  不能走索引


前缀索引:

前缀索引是针对于,我们所选择的索引列值长度过长,会导致

索引的高度增高,导致需要读取更多的数据页,mysql中索引树高度3-4层。

所以可以选择大字段的前面部分字符作为索引的生成条件。

4 b+tree索引高度影响因素

1.索引字段较长:前缀索引

2.数据行过多 : 分区表,归档表(pt-archive),分布式架构

3.数据类型:变长使用vachar,选择合适的数据类型。


索引的管理命令

什么时候创建索引:

按照业务语句的需求创建合适的索引,并不是将所有的列都创建索引。

索引不是越多越好.

将索引建立在,经常where group by order by join on ....的条件.

为什么不能乱建索引?

如果冗余过多,表的数据变化时,很有可能导致索引频繁更新,会阻塞业务的

正常更新需求。

2.索引过多,会导致优化器的选择出现偏差。

管理命令:

建立索引:

查询表的索引情况: 

desc city;

key pri聚簇索引 mul辅助索引 uni 唯一索引

show index from  city;

添加索引

alter table city add index idx_na(name);

删除索引

alter table city drop index idx_na;

压力测试 

我这里有一张200万的表,用mysql工具进行压力测试;

mysqlslap --defaults-file=/etc/my.cnf \

--concurrency=50 --iterations=1 --create-schema='world' \

--query="select * from world.test1 where name='刘备999' " engine=innodb \

--number-of-queries=100 -uroot -pluobiao123 -verbose

备注:concurrency 代表用户  number-of-queries 代表执行次数 ,下面是花费时间:

Benchmark

Running for engine rbose

Average number of seconds to run all queries: 102.955 seconds

Minimum number of seconds to run all queries: 102.955 seconds

Maximum number of seconds to run all queries: 102.955 seconds

Number of clients running queries: 50

Average number of queries per client: 2

可以看到用了102秒 

下面创建索引再次执行: alter table world.test1 add index idx_na(name);

结果如下:

Benchmark

Running for engine rbose

Average number of seconds to run all queries: 0.026 seconds

Minimum number of seconds to run all queries: 0.026 seconds

Maximum number of seconds to run all queries: 0.026 seconds

Number of clients running queries: 50

Average number of queries per client: 2

共花费0.026秒,效率提升3923倍.


--创建联合索引

alter table city add index idx_c_n(name,countrycode);

--创建前缀索引

alter table city add index idx_du(district(5));--截取前5位

回表带来的影响:

1.oi量级变大

2.oips增大

3.随机io会增大

怎么减少回表

1.将查询尽量可能用主键进行查询

2.设计理想的合理的联合索引

3.更精确的查询条件+联合索引

4.优化器的算法:MRR

跟新数据时,会对索引有影响吗? 数据的变化索引会实时更新吗?

例如 insert  一行数据  

对于聚簇索引会立即更新。

对于辅助索引,不是实时更新的。

在innodb内存机构中加入了 insert buffer(会话),现在叫change buffer。

change buffer的功能是临时缓冲辅助索引需要的数据更新。

当我们需要查询新insert 数据,会在内存中进行merge(合并)操作,此时辅助索引就是最新的。

问题3:双11是怎么搞的,数据库?

提前1-2周将热点商品数据,灌入到tair(reidis)集群中.

KAFKA,核心:队列加缓存.

你可能感兴趣的:(mysql 索引)