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

Wesley13
• 阅读 534

  上回刚刚讲到了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的性能

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

  这个公式是怎么写出来的以及怎么推导出来的嘟嘟不知道。但是从结果可以看出(假设你在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中使用

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

  主键会默认有一个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等等。。。

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

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这