【Mysql培训】Mysql数据库高级管理与性能优化实战---待重新编辑

基于Mysql 5.7

10.30:环境配置,介绍,特性,事务,重点是事务中的隔离性,锁,索’引

10.31:建立 索引、还原备份,

内容安排:

  Mysql背景案例分析

  Mysql介绍

  Mysql特性

  Mysql性能调优

  Mysql运行监控

  Mysql备份与恢复

  Mysql主从复制与读写分离

  Mysql分库分表之MyCAT

Mysql背景案例分析

  数据库在大促高并发场景下的作用

  大促高并发场景下数据库面临哪些考验?

  数据库优化方向?

    1.去IOE

    2.28原则,8读,2写。2读有效数据,8读无效数据。

Mysql介绍

  关系型数据库,其他关系型数据库Oracle,sqlServer,非关系型Redis,一些国产数据库,如达梦等。半结构化数据库。MariaDB?

  在数据库中,每个数据库有三个文件:一个样式(描述文件)、一个数据文件、一个索引文件。样式文件以.fmr为后缀,描述表的结构(列、列类型、索引等)。.ISD(ISAM)或.MYD(MyISAM),包含数据文件上的所有索引的索引树。.ISM(ISAM)或.MYI(MyIsam)该文件依赖于表是否有索引而存在。

  show warnings;

存储引擎

  存储引擎就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。有Myiasm,InnoDB,Merge等,Mysql8去除了Myisam引擎,主要保留了InnoDB。

  MyIsam:默认引擎(5.1之前),表级锁定,适用于大量的读操作的表、文件存储结构,串行的读写方式。

  InnoDB:默认行级锁,也支持表级锁,支持外键、事务处理,适用于大量的写操作的表,并行的读写方式。

  通过以下代码可以看到数据库的引擎:

show variables like '%engine%';

  上面是通过Navicat For Mysql的方式输入命令,也可通过C:\Program Files\MySQL\MySQL Server 5.7\bin>mysql -u root -p 即可进入命令行的形式。

  

事务

  通过begin开启事务,commit或者rollback结束事务。

BEGIN;//开启事务
insert into classtypes VALUES('t4','学英语');
COMMIT;//提交事务

  Mysql可通过 set autocommit=1; 修改是否自动提交,1表示自动提交,0表示不自动提交。Mysql的AutoCommit(自动提交)默认是开启,所以不开启事务的情况下,会自动提交sql。自动提交对Mysql的性能有一定影响,举个例子来说,如果你插入了1000条数据,Mysql会commit1000次的,如果我们把AutoCommit关闭掉,通过程序来控制,只要一次commit就可以了。

   ACID  https://blog.csdn.net/dengjili/article/details/82468576    

  查看事务隔离级别。

  show VARIABLES like '%iso%';

   

  若A表开启事务,B开启事务,A中插入数据,AB均不能查到数据。A提交事务,A能查到数据,B不能查到数据(Oracle此时能查到数据(默认读已提交),这是事务的I属性,隔离性,读未提交、读已提交可读取到,可重复读,串行化不可读到),B关闭事务,能查到数据。

 修改事务隔离级别。

set TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

 修改成功。

   在Navicat里通过set修改数据库隔离级别后, show VARIABLES like '%iso%'; 还是以前的隔离级别,需重启Mysql服务。

锁机制

  MyISAM,表级锁,对整个表文件进行锁定。开销小,加锁快,不会出现死锁。

  InnoDB,默认行级锁,也支持表级锁,对表文件中局部数据进行锁定,开销大,加锁慢,会出现死锁。哪种情况会出现死锁?

  查看表结构。

show CREATE TABLE classtypes;

表的结构数据如下:

    MDL=meta data lock,元数据锁,在事务开启期间,不能更改数据库结构,发生阻塞。如alert TABLE classtypes add num TINYINT(1); http://blog.itpub.net/29896444/viewspace-2101567/

  我们修改同一行数据classtype='t1',发生阻塞,提示错误。

 

然后我们修改classname,还是出错,把这两行都锁住了,这是因为classname不是索引。

 

   间隙锁。

   sql+ lock in SHARE mode

字段类型

  数值:tinyint,smallint,mediumint,int(默认长度11),bigint,decimal

  字符:varchar,char,text,blog

  时间:datetime,8位,1000-01-01 00:00:00 ——9999-12-31-23:59:59

     timestamp,4位,1970-01-01 00:00:01——2038

       date,3位,1000-01-01——9999-12-31

  一个表的字段有id,age,长度都是int(5),那么age最大长度是多少?

  如果,插入以下数据,9999超过了2^6-1,会不会出错。最大值int*5???

  枚举:enum,只能选择其一,如性别,一个enum字段有'M','F'两个,那么只能插入这两个中的其中一个。

索引

  目的:加快检索查询。

  分类:普通索引,唯一索引,主键索引,全文索引等。唯一索引可以为NULL,主键索引不能为NULL。建索引条件=区分度高,是查询条件

  先提出几个问题,为什么要加主键,加索引为什么会变快,为什么要给两个字段都加索引,为什么加了索引删除修改操作变慢?

  平时建表都会给表加一个主键,这个主键有什么用呢?事实上, 一个加了主键的表,并不能被称之为表。一个没加主键的表,它的数据无序的放置在磁盘存储器上,一行一行的排列的很整齐, 跟我们认知中的数据很接近。如果给表上了主键,那么表在磁盘上的存储结构就由【整齐排列的结构】转变成了【树状结构】,也就是上面说的【平衡树结构】,换句话说,就是整个表就变成了一个索引。也就是所谓的「聚集索引」。 这就是为什么一个表只能有一个主键, 一个表只能有一个「聚集索引」,因为主键的作用就是把表的数据格式转换成【索引】的格式放置。

 其中树的所有结点(底部除外)的数据都是由主键字段中的数据构成,也就是通常我们指定主键的id字段。最下面部分是真正表中的数据。 假如我们执行一个SQL语句:

  select * from table where id = 1256;

首先根据索引定位到1256这个值所在的叶结点,然后再通过叶结点取到id等于1256的数据行。 这里不讲解平衡树的运行细节(节点处采用二分法), 但是从上图能看出,树一共有三层, 从根节点至叶节点只需要经过三次查找就能得到结果。如下图:

假如一张表有一亿条数据 ,需要查找其中某一条数据,按照常规逻辑, 一条一条的去匹配的话, 最坏的情况下需要匹配一亿次才能得到结果,用大O标记法就是O(n)最坏时间复杂度,这是无法接受的,而且这一亿条数据显然不能一次性读入内存供程序使用, 因此, 这一亿次匹配在不经缓存优化的情况下就是一亿次IO开销,以现在磁盘的IO能力和CPU的运算能力, 有可能需要几个月才能得出结果 。如果把这张表转换成平衡树结构(一棵非常茂盛和节点非常多的树),假设这棵树有10层,那么只需要10次IO开销就能查找到所需要的数据, 速度以指数级别提升,用大O标记法就是O(log n),n是记录总树,底数是树的分叉数,结果就是树的层次数。换言之,查找次数是以树的分叉数为底,记录总数的对数,用公式来表示就是

用程序来表示就是Math.Log(100000000,10),100000000是记录数,10是树的分叉数(真实环境下分叉数远不止10), 结果就是查找次数,这里的结果从亿降到了个位数。因此,利用索引会使数据库查询有惊人的性能提升。

然而, 事物都是有两面的, 索引能让数据库查询数据的速度上升, 而使写入数据的速度下降,原因很简单的, 因为平衡树这个结构必须一直维持在一个正确的状态, 增删改数据都会改变平衡树各节点中的索引数据内容,破坏树结构, 因此,在每次数据改变时, DBMS必须去重新梳理树(索引)的结构以确保它的正确,这会带来不小的性能开销,也就是为什么索引会给查询以外的操作带来副作用的原因。

  

  建立索引:CREATE INDEX id on vote_records(id);    \G 纵向排列。

  查看索引:

  %,左边索引不生效,右边生效。检索数据超过30%不走索引。

 

 解决办法,reverse,覆盖索引(不需要回查,即通过查到的key再次查询得到数据)

复合索引,如一个索引为 A,B,那么 where A 会走索引, where A,B走索引, where B不走索引

  

lock锁表:

 插入数据会被阻塞:

 执行UNLOCK TABLES;后解锁,插入成功:

 查看日志是否开启:

mysql> show variables like 'log_%';
OFF是关闭,ON是开启。在C:\ProgramData\MySQL\MySQL Server 5.7下的my.ini中设置。

 

 重启服务后,可以看到log-bin成功开启了:

secure_file_priv:

 

 select * into outfile 'E:/test.sql' fields terminated by ',';

     CRUD truncate和delete的区别。

  有一个表user(id,age),有三条数据(id=1,age=18),(id=1,age=18),(id=1,age=18),执行delete from user后可rollback,插入第四条,id=4

  执行truncate,不可rollback,插入第四条,id=1

  show processlist;

  C:\ProgramData\MySQL\MySQL Server 5.7\Data下的ib_logfile0是全do日志,包括select.宕机用这个。主从用mysql-bin-00262日志。

show VARIABLES like '%innodb_flush_log%';

   

  为什么只读模式,5.7比5.6快3倍?怎么优化的?

  集群(Cluster):

    多个mysql服务器,减轻数据库负担。主从分离,读写分离。master用来写,slave用来读

查询是否开启告诉查询缓存,

  tuning-primer.sh

常用函数

预防死锁:

开发规范:

优化:

开发同学和DBA都需要了解业务情况:

  区分SQL的执行环境,是前台还是后台?

  评估SQL的执行频率,每天千万次查询和前次查询是不一样的。

  评估SQL返回的数据量,关心每条数据还是只关心前100条?关心所有字段,还是真正对用户有意义的字段?

  评估表的数据量和增量,从而评估SQL的执行效率。

开发同学写SQL时要注意:

  尽量避免查询的结果超过正常的需求,很少有人关心10W页后的数据。

  尽量减少表之间的关联,多表之间的关联要使用表的别名来引用表的字段。

  不要使用select * ,具体到字段。

  尽量减少使用distinct,like,group by,oder by等。

  尽量减少子查询,也不要写成inner join格式。

  一定要使用绑定变量。

状态查看:

 show global status like '%variables%';

  

 show full processlist;

 

show engine innodb mutex;

 

show engine innodb status;

 

show profile;

 

 

show warnings;

 mysql show query;

 查看profile是否开启:

select @@have_profiling;

show status like '%perf%';

show engine performance_schema status;

 

 

 select THREAD_ID,NAME,TYPE,INSTRUMENTD from threads;

查询读写top5的等待:

select EVENT_NAME,COUNT_READ 'read',COUNT_WRITE 'write',COUNT_MISC 'misc',(COUNT_MISC+COUNT_WRITE+COUNT_READ) as SUM_IO from file_summary_by_event_name order by 5desc limit 5;

查询读写top5的file

统计在表上锁的top5

统计发生table lock消耗时间最高的表

Mysql特性

  开源、免费、跨平台、安全性、成本低、支持各种开发语言、支持强大的内置函数、数据存储量大?

Mysql性能调优

分区:把一个表的数据分成N多个区块,分区后还是一张表,需要一个分区键,不是分区键会扫描所有分区

  作用:提升数据库的访问性能

  适用:平时访问量不是特别大,表结构变更也不多,而且历史数据访问量低下,可能会做成分区表,这样平时基本上只要访问最近的分区段,还有利于老数据的清理。

分区类型
range分区:基于一个给定的连续区间范围(区间要求连续并且不能重叠),把数据分配到不同的分区
list分区:类似于range分区,区别在于list分区是居于枚举出的值列表分区,range是基于给定的连续区间范围分区
hash分区:基于给定的分区个数,把数据分配到不同的分区
key分区:类似于hash分区
注意:无论哪种分区,要么你分区表上没有主键/唯一键,要么分区表的主键/唯一键都必须包含分区键,也就是说不能使用主键/唯一键字段之外的其它字段分区。

创建表时创建分区:

-- 创建分区表
CREATE TABLE `tbl_user_part` (
   `id` int(11) NOT NULL ,
   `username` varchar(255) DEFAULT NULL,
   `email` varchar(20)     DEFAULT NULL,
   `age` tinyint(4)        DEFAULT NULL,
   `type` int(11)          DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP -- PRIMARY KEY (`id`,`age`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 PARTITION BY RANGE (age) ( PARTITION p0 VALUES LESS THAN (20), PARTITION p1 VALUES LESS THAN (40), PARTITION p2 VALUES LESS THAN (60), PARTITION p3 VALUES LESS THAN (80), PARTITION p4 VALUES LESS THAN MAXVALUE );

表结构:

创建表后创建分区:

 

 

https://blog.csdn.net/vbirdbest/article/details/82461109

分表:把一张表分成多个表。

  作用:提升数据库的访问性能。

  适用:数据量非常大,而且访问上没有绝对的热点,基本上所有数据都会被访问到。

分库:把一个数据库分成多个数据库

  作用:提升数据库的访问性能。

Mysql运行监控

Mysql备份与恢复

备份1

  Mysql导入、导出。导出 mysqldump,

 mysqldump -uroot -p examol vote_records>D:/vote_records.sql  一定不能加分号!!!要在bin下面执行, 不是Mysql里!!!

  导入 source,先  use database; 选择导入的数据库,

  source D:/Program Files/feiq/Recv Files/vote_records/vote_records.sql;  导入数据。

 

还原:

 https://www.cnblogs.com/tonnytangy/p/7779164.html

 

Mysql主从复制与读写分离

要求:

1.主库、版本一致

 2.主库中的日志备份,从库日志还原增量

 3.主库产生增量日志,从库同步增量日志

步骤:

 1.p34=

 Mysql分库分表之MyCAT

猜你喜欢

转载自www.cnblogs.com/zhuii/p/11765675.html