上回刚刚讲到了B-Tree 这次来简单学学B-Tree索引
B-Tree中每个节点包含:
1.本节点所含关键字的个数。
2.指向父节点的指针
3.关键字
4.指向子节点的指针
关于B-Tree的规则
1.m阶的B-Tree 每个结点至多可以拥有m个子节点,根结点至少有两个子节点
2.根结点的关键字(key) 的个数为1到m-1个,而每个非根节点至少要有【m/2】个(向上取整)子节点,所以关键字的个数就在【m/2】-1到m-1个
B-Tree的性能
这个公式是怎么写出来的以及怎么推导出来的嘟嘟不知道。但是从结果可以看出(假设你在N个数据里面查,每次都除以2,需要除几次才能定位到这个数据)B-Tree的性能相当于二分查找,跟阶数(M)无关。
Full-text索引(全文索引,最左前缀索引)
1.Full-Text索引的存储结构也是B-Tree,主要为了解决在我门需要用like查询的低效问题。只能解决 ‘xxx%’的like查询
2.主要通过关键字信息的全数据排列(比如有一个字符串ABC ,那么该字符串的索引有3个A,AB,ABC,注意仅仅从左到右顺序,如果 查询的时候使用了 like AB% 则会借助AB来立刻定位出AB和ABC)
普通索引
大多数情况下我们都使用B-Tree 索引
索引操作
1.MySql创建索引
create index index_name on table_name (column(length))
alter table table_name add index index_name(column(length))
为什么要加上length呢?因为如果太长的话磁盘占用空间太大
create table table_name (
id int not null auto_increment,
title varchar(32),
primary key(id),
index index_name(title(length))
)
2.查看索引
show index from table_name
show keys from table_name 只能在MySql中使用
主键会默认有一个B-Tree 索引,InnoDB添加的默认索引也是B-Tree
3.删除索引
drop index index_name on table_name
alter table table_name drop index index_name
alter table table_name drop primary key
唯一索引
与普通索引类似,不同点在于,索引列的值必须唯一,但是允许有空值(和主键不同)。如果是组合索引,则列值得组合必须唯一,创建方法和普通索引类似
创建唯一索引
create unique index index_name on table_name(column(length))
alter table table_name add unique index_name(column(length))
create table table_name(
id int not null auto_increment,
title varchar(32) ,
primary key(id),
unique index_name(title(length))
)
全文索引
FullText索引仅仅可用于MyISAM表。可以从char,varchar,text列中作为create table 语句的一部分被创建,或者是创建完表之后使用alter table 或者create index 被添加
尽量是先建立表导入数据再创建FullText索引,而不要先建立FullText索引再导入数据(不过数据量太大的话,建立全文索引非常耗时耗硬盘)
创建全文索引
create fulltext index index_name on table_name (column(length))
alter table table_name add fulltext index_name(column)
create table table_name(
id int not null auto_increment,
title varchar(32),
primary key(id),
fulltext index_name(title))
)
组合索引(最左前缀)
将多个列组合成一个索引
举个栗子:
create table article(id int not null,title varchar(255) ,time date) 针对title 和 time 建立组合索引:
alter table article add index index_title_time (title(50),time(10))相当于建立了下边两组组合索引 (title(50)取的是前50个字符)
--title,time
--title
至于为什么没有time这个索引。MySql定义的最左前缀,就是这么定的,从最左边开始组合
如果使用 select * from article where time =1234567890 或者 select * from article where time=1234567890 and title='张三';就不会使用到上面的索引
创建组合索引
create index index name on table_name (column1(length),column2(length).....)
索引的优化
索引虽好,但是也不要贪杯哦。因为,索引是针对查询的一种提高效率的方式。但是如果增删改过于频繁的话,每次进行增删改都有可能去重构索引。
1.无效的索引:如果列中存在Null值,则不会被包含在索引中(这一行无效)。组合索引如果有一列包含null值,则这一列对于组合索引来说无效。所以在数据库设计时不要让字段默认值为null(可以设定默认值)
2.索引的长度尽量要短,基本上在char(255)范围内,截取前10个或者20个字符就能保证索引唯一。短索引不仅可以提高查询速度,还能节省磁盘空间和IO操作。
3.MySql查询只使用一个索引,因此如果where 子句已经使用了索引。那么order by 中的列是不会使用索引的。如果数据库的默认排序符合你的需求,就不要使用order by 了,尽量不要包含多个列的排序,如果需要最好将这些列创建复合索引。
(如果想看数据库的查询方式可以使用 explain + 查询语句)
4.尽量不要使用like ,如果使用 ,则 like ‘%aaa% ’不会使用索引 而 like ‘aaa%’会使用索引
5.不要再列上面进行运算
比如:select * from users where year(date)<2007 将会计算date列上的每一行的字段,索引失效,全表扫描
可以改成:select * from users where date < '2007-1-1'
索引总结
1.MySQL 在 < <= = > <= between in 以及某些时候的like(不用% 或者 _ 开头)的情形下面才使用索引(嘟嘟猜测不同的操作符会导致索引的使用率不同),每一张表可以建立最多16个索引,但是太多并没有什么卵用
2. != , not in 等这种操作符也会使用到索引,想要查询是否用到索引以及是否为全表扫描。可以使用 explain + 查询语句 查看具体信息
常见优化策略
1.尽量避免全表扫描。(最好where 或者 order by 上面建立索引)
2.避免在where 上进行null 判断,否则会导致引擎放弃索引是用全表扫描(设置默认值为0等)
3.避免使用不等值判断,否则引擎会放弃使用索引而进行全表扫描
4.避免使用or逻辑 (全表扫描)
select id from t where num=10 or num=20
可以改成
select id from t where num = 10
union all
select id from t where num = 20
5.慎用in 和not in 逻辑(全表扫描)
6.注意模糊查询(%在前面会导致全表扫描)
如果必须用%开头,则推荐使用全文搜索引擎
7.避免查询条件中字段计算(会导致每个字段都进行计算)
8.避免在查询条件中对字段机型函数操作(原因同上)
select id from t where substring(name,1,3) = 'abc'
优化成 select id from t where name like 'abc%'
9.使用复合索引必须用到第一个字段才会用到索引
10.表格字段尽量使用数字类型字段,数字类型与字符串类型相比,搜索引擎会逐一比较每一个字符
11.查询字段越多返回效率越低,所以尽量不要使用*
大总结:
到了这里嘟嘟的数据库到底优化啥了都就算是初步的写完了(还有后续),第一个原因是嘟嘟在网上扒的视频资料没有了。嘟嘟也相信这份资料也是一份简单的介绍。比如explain + 查询语句下面的type项下有好多的选项(ref ,range ,all ,index 等等)都没有提及,还有什么MySql和MyCat的分库分表什么的。嘟嘟也知道什么东西都不能一蹴而就,所以这个MySql的文章还是没有写完。以后嘟嘟自己学习的过程中如果发现MySQL实现优化的细节,还会继续写567等等。。。
写这个博客相当于对着视频记笔记。初衷也是为了和面试官对吹,但是发现这些东西好像不够吹。所以嘟嘟还需要压榨时间效率。去深入学习编程,学习数据库等等。这个系列的东西,嘟嘟准备停一下。放空放空脑子。巩固一下这知识。最后勉励一下自己,再努力的压榨一下自己的时间利用率,提升自己。去做自己认为会往更好的方向发展的事情。毕竟在这个年代,放松毫厘,随着时间推移,会差之百里。挣扎,加油。