MySQL优化一

好吧整理的是再是太多了 , 一次放不下要分两回 ! 这可是我沥尽心血弄出来的 , 如果你看到了感觉还不错 , 那就给我点个赞吧 !

太多了

这篇里面主要涉及一些结构、锁 以及myisam 和 innoDB 的差异等

数据结构

B+Tree的数据结构

在算法搜索的时候会非常的高效,这种数据结构特别适合现在的硬盘这个存储的介质。

扩展:操作系统上的文件系统

也是使用的B+Tree的数据结构。这个不区分操作系统。

非聚(集)簇结构

myisam 的索引结构 (图就不截了)

image.png

总结 : 主索引是不能重复的,我们的索引下面的数据去保存的是innoDB(硬盘数据区的编号),找到索引对应的编号,通过这个编号区数据区找到这个数据,就把需要的数据返回给客户端

普通索引

image.png

总结 : 这个就是普通索引,索引的值是可以重复的,和主索引是一样的

聚(集) 簇结构

主索引 :

image.png

总结 : innoDB 索引的数据在一起的,所以我们创建 innoDB 与 myisam 是不一样的。innoDB必须创建主键 ID。必须要创建主键 ID,必须实现 auto_increment。 保存索引的 ID 是有序增长的,如果不是有序增加的,当你插入一条 ID 小于已经存在的 ID 的时候,这个时候 ID 就会去排序,后面的值就会在数据区进行移动,这个移动过程就会消耗IO,后面移动的数据越大,这个消耗就越大。 如果不创建,他会自动去找一个可以作为主键的值,如果没有他会隐藏创建一个主键的值

普通索引

image.png

普通索引下面的输进去保存的是主键的 ID , 这些 ID 会在进行普通索引搜索的时候 , 返回 , 返回之后再到主键索引去进行搜索 . 这就说明 , 如果 innoDB 不实用主键进行查询 , 就会出现二次遍历 , 第一次遍历普通索引 , 第二次遍历主键索引 普通索引 , 第二次遍历主键索引

总结 :

myisam 的有瘾结构都是一样的 , 主索引比其他索引就是多了一个不重复的功能 , 所以在使用 myisam 的时候 , 创建索引 , 可以任意 . 但是以数字 ID进行自增长的索引 , 暂用的长度与空间更小更小更少 , 还是建议使用 auto_increment innoDB 的主索引与普通索引完全不一样 . 主索引之遍历一次 , 普通索引必须进行两次遍历才能得到结果

没想到我也能整一篇理论这么多的东西 ~ 兄弟们不要紧张这些内容主要来源是百度

************************** 我是分割线 **************************

MyISAM 与 innoDB 引擎的区别

  • 数据结构不一样
  • MYISAM 不支持事物,INNODB 支持事物
  • MYISAM 不支持外检,INNODB 支持外检
  • MYISAM 支持全文搜索,INNODB 不支持全文搜索(在 5.6 以后支持)
  • MYISAM 支持地理位置空间索引,INNODB 不支持
  • MYISAM 支持压缩 , INNODB 不支持压缩

MYISAM 引擎与 InnoDB 引擎的备份与还原

数据库备份

数据备份需要工具

找到工具(Linux 中)

image.png
备份 innodb
mysqldump -u 用户名 -p 库名 表明 > 保存的绝对路径
image.png
还原操作
mysql -u 用户名 -p 库名 < 表的绝对路径
image.png
对数据库进行备份

备份方式一

mysqldump -u 用户名 -p 数据库名 > 保存的绝对路径

image.png

查看备份的数据内容: 备份的文件内容只有创建表与数据。并没有创建库的操作。所以使用这个还原的时候,一定要有库名。

备份方式二

mysqldump -u 用户名 -p -B test > 保存的绝对路径
image.png

查看备份的内容: 这样备份的内容有创建库的操作

还原数据库
mysql -u 用户名 -p < 库文件的绝对路径
image.png

总结 :

备份的文件是 SQL 文件 , 里面的内容就是sql语句 , 所以我们是可以修改里面的内容的(既然是备份,就不要轻易修改)
还原的时候,一定不要删除表 , 如果有同名的表或者库名 , 应该重命名 !

************************* 我是分割线


如果你看到了这里很好 , 你即将来到我们这篇文章的核心地带

MySql 中的执行计划

what ? 执行计划 ?

就是mysql自己生成的对于 SQL语句执行效果的说明结果。

作用

  • 可以让我们对 SQL 语句的性能有详细的了解
  • 可以让我们对 SQL语句使用了索引有了解
  • 可以让我们对 SQL 语句扫描了多少数据有了解

基本语法

explain SQL 语句
重点 : 针对查询 SQL (select)

explain 详解

image.png

(⊙o⊙)… 这个有点看不清 换个方式

image.png
  • const:扫描数据一行或者2行的时候。
  • ref :这个扫描的范围比range小。
  • range:这个扫描的范围比index的小
  • index:这个就是索引的扫描
  • ALL:硬盘数据的扫描 type 越小越好 possible * keys : 可能用到的索引
  • key : 用到的索引
  • key len : 索引长度
  • rows : 扫描的行 EXTRA :
  • Using filesort : 这个参数出现就要优化 SQL 了 , 这个文件排序 , 效果最差
  • Using temporary : 使用了临时表
  • Using index : 这个是 索引覆盖 , 就是查询的时* 候 , 在索引上面找到了 , 不需要在查数据直接返回给客户端 !
  • Using where : 数据过滤

这里讲一个分页优化 MySQL

limit n 20 :

加入有 3000w 数据,使用这种分页可定会挂掉这种分页只适合数据量小的时候操作

image.png

解决方案

where id>n limit 10;
image.png

两种特殊的索引结构

全文索引

其他几种索引,都是以字段值来进行索引的,全文索引事宜字段里面的内容来进行全文索引的 .全文索引能够所搜到一个字段值里面的某个单词

全文索引是 myisam 支持的 , innoDB 在 5.6 以后才支持

全文索引的使用方法:

select *from table_name where match(字段) against(搜索内容)

创建全文索引:

alter table table_name add fulltext  索引名(字段))

删除全文索引

alter table table_name  drop index 索引名
或
alter table table_name drop key 索引名

使用案例 :

创建表 :

image.png

插入数据 :

image.png

创建全文索引 :

alter table `fulltext` add fulltext full(content);
image.png

查询验证 :(搜索)

select * from `fulltext` where match(content) against('dream');
image.png

总结 : 全文索引对搜索的词汇自动过滤 , 会过滤一些高频词汇 , 就像这些词汇在每一个文章里面都会有很多 , 当我们进行搜索的时候 , 这些词相对来说是没有意义的 , 会被过滤掉 , 这个过滤是内部实现的 , 是不可控的 !

说明 : 全文索引使用较少 , 特别是汉字 , 搜索的时候必须使用第三方工具支持 (稍后再讲汉字搜索)

前缀索引

自己去百度吧 ~~~~

MySQL 中的其他功能

慢日志(执行超市就记录在日志里)

查看慢查询开关

image.png
slow_query_log :默认是关闭:OFF; 开启状态是ON。
    使用数字表示 : 1 开启     0 关闭
slow_query_log_file:慢日志的文件路径。
    不要修改,可能修改的地方没有权限

开启查询

set global slow_query_log = 1 ;
image.png

设置慢时间

set long_query_time = 1.1111;
image.png

查看慢日志文件的所在地

image.png

工作模式打开方式

tail  -f  文件路径
image.png

一直打开,有内容更新时,直接打印

案例 :

select * from myisam where content like '%毕业%';
image.png

查看日志

image.png

SQL 语句缓存

SQL 语句缓存 , 就是把 SQL 语句查询的结果缓存起来 , 下次在执行查询的时候 , 就会把这个结果返回给客户端 , 不用在进行查询了 !

查看是否开启

show variables like '%query_cache%';
  • have_query_cache :表示MYSQL服务器,支持缓存:YES
  • query_cache_limit :缓存单SQL的值最大结果是1048576(B) : 1M
  • query_cache_min_res_unit :数据块是4K来划分。
  • query_cache_size :设置缓存的总大小:0就是没有给空间。
  • query_cache_type :ON就是已经支持了缓存。 总结。没有给大小,支持了也没有缓存。

查看缓存的状态!

image.png
  • Qcache_free_memory :没有使用的空间:
  • Qcache_hits :缓存的命中数量!
  • Qcache_inserts :缓存的插入次数
  • Qcache_lowmem_prunes :超过缓存的界限。数据量太大。
  • Qcache_not_cached :不缓存:
  • Qcache_queries_in_cache :缓存的SQL语句数量

开启缓存,设置大小

set global query_cache_size = 1024 * 1024 * 64;

说明 : 计算机大小数据设置最好是双数 , 至于为什么 我也不知道查百度吧

案例 :

image.png

插入了一条,保存了一条数量

使用SQL语句查询:

image.png

相同的 SQL , 命中增加一条 注意 : SQL 语句任意改变都是新的 SQL 语句 , 对于这个缓存来说 , 如 : where编程了 where (多了个空格),也是一个新的~ what 总结到这里我发现这东西 , 工作中根本用不到~~~

既然用不到 , 那就清空(人工清空缓存)

reset query cache;

MySql 里面的锁有几种形式

  • 表锁 : myisam 实现的表锁 , 表锁的性能非常好
  • 行锁 : innoDB 实现的行锁 , 性能很好 表锁与行锁最大区别在于并发 , 行锁的并发比较大 . 功能 :
  • 读锁 : 共享锁 : 因为本用户可以读 , 其他也可以读 , 大家一起都可以读 , 所以叫共享锁
  • 写锁 : 排他锁 : 因为这个用户想写 , 其他用户就不可写 , 所以只能一个人写 其他锁
  • 悲观锁 :
  • 乐观锁 : 自己百度吧

表锁 myisam 引擎

  • 照一张 myisam 引擎表
image.png
  • 实现锁的功能
读锁 :
        开始 : lock tables table_name read;
        结束 : unlock tables;
写锁
        开始 : lock tables table_name write;
        结束 : unlock tables;

案例 : 读锁开始 :

image.png

当前用户开始查询

image.png

其他用户也可以使用

image.png

当前用户更新从挨揍

image.png

提示我们已经被锁定 , 不能进行更新 , 也就是不能修改

image.png

其他用户执行更新 :

image.png

出现进程等待 , 等待其他用户关闭锁 , 他就能更新成功 , 但是有等待时间 , 时间操作会报错 结束锁

image.png

总结 : 当前用户可以读 , 其他用户也可以读 当前用户不可以写 , 其他用户也不可以写

写锁案例 : 开始写锁

image.png

当前进程查询

image.png

其他进程查询

image.png

其他进程出现了查询等待 .

当前进程可以更新数据

image.png

其他进程更新

image.png

出现了 进程等待 解锁

image.png

行锁 innoDB 引擎

事物(transaction) 及其 ACID 属性

  • 原子性(Atomicity) : 事物是一个原子操作单元 , 其对数据的修改 , 要么全部执行 , 要么全都不执行
  • 一致性(Consistent) : 事物的开始和完成 , 数据都必须保持一致状态, 这意味着所有相关的数据规则都必须应用事物修改 , 以保持数据的完整性 ; 事物结束的时候 , 所有的内部数据结构也都必须是正确的 .
  • 隔离性(isolation) : 数据库系统提供一定的隔离机制 , 保证事物在不受外部并发造作影响的"独立"环境执行 . 这意味着事物处理过程中的中间状态对外部是不可见的 , 反之亦然
  • 持久性(Durable) : 事物完成之后 , 他对数据的修改是永久性的 , 即使出现系统故障也能保持 必须在是事物里面 :
  • 开启事物 : begin
  • 结束事物 : commit 读锁 :
SQL语句 + lock in share mode

写锁 :

SQL + for update

案例 : 开始事物 :

image.png

读锁

image.png

其他用户加读锁

image.png

当前用户修改

image.png

其他用户去修改

image.png

其他用户修改 , 出现了进程等待 结束事物

image.png

总结 :

当前用户开启读锁的时候 , 其他用户也可以使用读锁 . 当前用户可以修改数据 , 其他用户是不可以修改的 .

写锁

开始事物

image.png

当前用户写锁

image.png

其他用户使用共享锁尝试一下 :

image.png

其他用户不能使用共享锁 当前用户修改内容

image.png

其他用户不能修改内容 结束事物

image.png

同一个表中 , 不同的数据

开启事物

image.png

对一个行,数据进行写锁

image.png

其他用户 , 操作其他行的数据

image.png

对其他行的数据操作是成功的 证明其使用的是行锁 当用户操作其他数据 :

image.png

操作成功 其他用户查看当前用户操作的数据 , 出现了进程等待 总结 : 当前用户修改过的数据 , 都会加 排他锁 结束事物 :

image.png

总结 : innoDB 确实是行锁 , 但是innoDB 也可以实现表锁 说明 : innoDB 的锁是加载索引上面的 , 如果你使用的数据不是索引数据 , 就会出现表锁 . innoDB 的行锁可以自己解决锁冲突 , 而表锁是 mysql 实现的 , 与 innoDB 没有关系 , 如果出现锁冲突 , 就没有办法自己解决 !

锁冲突

当前用户第一条数据需要 ID1 , 第二条数据需要 ID10 其他用户第一条数据需要 ID10 , 第二条数据需要 ID1 所以写代码的时候 加锁一定要有顺序 , 不要随便跳转位置

验证表锁

  • 验证表结构
image.png

这里 id 和 passwd 添加了 索引

  • 对 name 进行了加锁擦欧洲哦 开始事物
image.png

对 xiao3333 加写锁

image.png

其他用户对 xiao3333 加排他锁

image.png

对这个值加排他锁 , 不成功 , 是正常的 , 符合预期 其他用户对 xiao11111 家排他锁

image.png

这个值对没有加排他锁 , 也不成功 , 就验证了 , 当前用户是加的表锁 结束任务 :

image.png

name : 没有添加索引

对 passwd 字段进行验证 开始事物

image.png

对 28ef7f90c15dc88dfe68d2912d22c8a7 值进行加排它锁

image.png

其它用户对 28ef7f90c15dc88dfe68d2912d22c8a7 值进行加排它锁

image.png

其他用户加锁不成功 , 符合预期 其它用户对 ff766a6f53fd4e4f4d615f44f59bfee9 值进行加排它锁:

image.png

加锁成功,符合预期 提交事物 :

image.png

innoDB : 引擎只有在有索引的数据字段上才会实现行锁 , 在非索引字段是表锁 , 所以索引对于 innoDB 是非常重要的 innoDB 引擎 ,尽量不要使用范围 , 如果你使用 id > 1000 加排他锁 , 就表示把 id > 1000 的所有值进行了加锁

PHP 实现锁+压力测试

需求 : 把访问次数 , 记录到表里面

  • 创建一张表 :
image.png

预热 :

image.png
  • 代码实现功能
image.png
  • 访问
image.png
  • 查看数据
image.png
  • 并发测试 这里有个压力测试软件 : ab 这个 ab 软件 , 就是 Apache 自带的
image.png

ab -n number -c number url地址 -n 总的访问量 -c 并发访问量

  • 使用 ab 进行测试
image.png

查看结果

image.png

结果不理想 , 有差异

再次测试

image.png

查看结果;

image.png

还是有差异

  • 给代码加锁
image.png

再次测试

image.png

查看数据 :

image.png

说明 : 加锁之后 , 我们的并发 , 就是串行执行的 . 加锁成功的就操作数据 , 加锁不成功的 , 就等待加锁成功之后继续操作 . (访问速度慢) 注 : 还有文件锁 , 通常是单服务器使用 , 自行百度吧

================== 下一章主从服务器 ==================

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容