MySql的数据库优化到底优啥了都??(4)

  上回刚刚讲到了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等等。。。

    写这个博客相当于对着视频记笔记。初衷也是为了和面试官对吹,但是发现这些东西好像不够吹。所以嘟嘟还需要压榨时间效率。去深入学习编程,学习数据库等等。这个系列的东西,嘟嘟准备停一下。放空放空脑子。巩固一下这知识。最后勉励一下自己,再努力的压榨一下自己的时间利用率,提升自己。去做自己认为会往更好的方向发展的事情。毕竟在这个年代,放松毫厘,随着时间推移,会差之百里。挣扎,加油。

猜你喜欢

转载自www.cnblogs.com/ruishui30005921/p/11240850.html