A102_关系型数据库优化

1.内容介绍

1. 关系型数据优化概述;(了解)
2. 定位慢SQL;(掌握)发现问题
3. 分析慢sql;(掌握)分析问题
4. 常规优化;(掌握)解决问题

2.关系型数据优化概述

2.1.为什么需要优化-关系型数据库瓶颈
2.1.1.高并发读写需求

网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。例如:双十一购物
双十一购物节,号称优惠比较多。所以很多人都在那天购物,特别是11.11凌晨的时候,成千上万或上亿,一起查询、浏览商品,下单购物。实质上,商品订单等信息是保存到数据库中的,那是不是很多人同时获取数据库连接,同时操作数据(读写),操作完成后关闭连接。那,是不是要同时支持很多连接,并且读写。那,现状我们一台数据库最大连接数是不是有限的。不能满足很多人同时读写,是有瓶颈的。
集群和分布式

2.1.2.海量数据的高效率读写

网站产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的.例如:商品表
像天猫、京东等购物商城,某些数据是巨大的,比如说商品,用户等。存放到数据库中会有怎么样的效果呢?是不是一张包含很多数据(上亿条记录)的表,那我们查询、插入起来是不是速度会很慢。也就是说海量数据表的的读写速率比较低。

分表、分库

2.1.3.高扩展性和可用性

在基于web的结构(即浏览器/服务器)当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展 是非常痛苦的事情,往往需要停机维护和数据迁移.
动态添加服务器一台数据库服务器扩充到多台时,不下电情况是很难做到的。
单点故障:一台数据库服务器挂了。业务就中断,期望去找还好的数据库继续提供服务。

集群

2.2.关系型数据库的优化技术整体介绍

最终我们对数据库的所有操作都会转换为一条sql的执行.

对关系型数据库的优化是一个综合性的技术,主要包括
1、找出执行效率低Sql(定位慢查询)-发现问题
2、分析慢Sql  expain sql            -分析问题
3、优化                           -解决问题
	3.1 单机(表结构、索引、Sql(代码问题)):
		表
	  		合适表结构 3NF和反3NF
	  		合适引擎
	    索引
	    分表(垂直分表和水平分表)
	    Sql优化技巧
	3.2 多机(IO瓶颈):
		集群(读写分离,让多台服务器提供服务)
		分布式(把不同的业务分给不同的集群处理)
    3.3 其他优化方案
       缓存 es 页面静态化

1、优化方案不仅可以适用在mysql,还可以使用于oracle等关系型数据库,只是命令不同罢了。
2、优化时先考虑单台数据库服务器,如果单台优化完成后,实在满足不了需求再考虑多机集群和分布式。(有的公司不会使用多台数据库)

2.3.准备数据

见“准备数据.doc”

2.4.小结

3.定位效率低的SQL

3.1.定位慢查询-找出执行慢sql
3.1.1.原理

我们使用数据库,实质上就是连接数据库,发送SQL、服务器执行SQL并返回结果、关闭连接。也就是所以的SQL语句MySQL服务器都能感知到,比如执行了那些SQL,都执行了多少时间等。我们做优化是不是就是找出执行时间长的Sql进行优化。问题是: 如何从一个大项目中,迅速的定位执行速度慢的语句. (定位慢查询)

所有sql都是mysql执行,当它发现客户端执行sql慢的时候,会把结果记录下来。方便用户查找定定位。

3.1.2.查询数据库(mysql)基本状态

首先我们了解mysql数据库的一些运行状态(比如想知道当前mysql运行的时间/一共执行了多少次select/update/delete… / 当前连接/最大连接)
1)运行多久

show status like 'uptime';

2)CRUD执行次数

show status like '%Com_%'
CRUD
show status like '%Com_select%'
show status like '%Com_insert%'
show status like '%Com_update%'
show status like '%Com_delete%'

Show session/global status like '%Com_select%'

☞ show[session | global]status like … 如果你不写[session | global]默认是session 会话(指取出当前窗口的执行),如果你想看所有(从mysql 启动到现在),则应该 global。

INNODB
show status like '%Innodb_rows%';

3)查询所有连接数

show status like 'connections' 

4)查看服务器响应的最大连接数

show status like 'Max_used_connections'    
通过查询(工作环境)最大并发连接数可以配置作为我们配置mysql最大连接数的依据。
通常,mysql的最大连接数默认是100, 最大可以达到16384(理论上)。
3.1.3.定位慢查询

1)查询慢查询次数
show status like ‘slow_queries’ 慢查询,通常指花了2S以上的查询(默认10s)
在这里插入图片描述

2)查看和修改慢查询时间阈值
show variables like ‘long_query_time’ ; //可以显示当前慢查询时间
set long_query_time=1 ;//可以修改慢查询时间
在这里插入图片描述
在这里插入图片描述
注意:直接修改global 的long_query_time 之后在当前的的窗口中是没有效果的,在新打开的窗口中才会有效果。如果想让本窗口也有效果 的话,不用加 global关键字。

3)把慢查询记录到日志中
bin\mysqld.exe --safe-mode --slow-query-log [mysql5.5 可以在my.ini指定]

注意事项:
1 必须在mysql的安装目录执行,因为执行的使用依赖于my.ini,
2 慢查询日志会输出到data.dir
3 以下文件不要乱删,乱修改,会导致mysql没法启动
在这里插入图片描述
步骤总结:
1)关闭原有mysql服务
2)以支持记录慢sql的方式来启动mysql
3)设置慢查询时间阀值
4)构造慢sql
5)到日志文件中找慢sql(data.dir)

什么时候开启慢查询?
   系统中所有sql都执行一遍,才能判断是否有慢sql。什么时候开启能覆盖所有sql执行?
开发者自验:
     开发完成后,需要统一打包,统一部署,统一验证。
测试人员测试:
     测试人员需要测试所有功能。
项目上线:开一段时间,把它关了.或者不开
     用户用了所有功能。
3.2.explain(分析sql语句)

通过 explain 语句可以分析,mysql如何执行你的sql语句.
在这里插入图片描述
在这里插入图片描述

3.3.小结

4.优化1-单机优化

4.1.范式&存储引擎
4.1.1.范式(规范)-常见有三种规范3NF

表的范式,是首先符合1NF, 才能满足2NF , 进一步满足3NF
1)1NF
1NF: 即表的列的具有原子性,不可再分解,即列的信息,不能分解.只要数据库是关系型数据库(mysql/oracle/db2/sysbase/sql server),就自动的满足1NF.关系型数据库中是不允许分割列的。
2)2NF
2NF:表中的记录是唯一的.通常我们设计一个主键来实现
在这里插入图片描述

3)3NF
即表中不要有冗余数据, 就是说,表的信息,如果能够被推导出来,就不应该单独的设计一个字段来存放.举例说明不满足:学生、班级
在这里插入图片描述
4)反第3NF
反3NF :没有冗余的数据库表未必是最好的数据库表,有时为了提高运行效率,就必须降低范式标准,适当保留冗余数据。具体做法是: 在概念数据模型设计时遵守第三范式,降低范式标准的工作放到物理数据模型设计时考虑。降低范式就是增加字段,允许冗余。
举例说明:相册
在这里插入图片描述
相册是浏览次数是相片点击次数之和。
在这里插入图片描述
为了提高效率,直接在相册表添加浏览数。方便查询!
在这里插入图片描述
订单,订单明细,课程中加入一些冗余设计

数据库触发器
https://www.cnblogs.com/zh-1721342390/p/9602941.html

CREATE TRIGGER

4.1.2.存储引擎-创建表时要选择存储引擎

分类:mysql:myisam,innodb,memory

1)优缺点
问 MyISAM 和 INNODB的区别(主要)******

  1. 事务安全 MyISAM不支持事务,INNODB支持
  2. 查询和添加速度 MyISAM速度快,INNODB速度慢
  3. 支持全文索引 MyIsam支持,innodb不支持
  4. 锁机制 MyIsam表锁 innodb行锁
  5. 外键 MyISAM 不支持外键约束, INNODB支持外键. (通常不设置外键,通常是在程序中保证数据的一致)
    在这里插入图片描述

2)使用场景
MyISAM存储引擎
如果表对事务要求不高,同时是以查询和添加为主的,我们考虑使用myisam存储引擎. 比如 bbs 中的 发帖表,回复表.

INNODB存储引擎:
对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,账号表.

Memory 存储
比如我们数据变化频繁,不需要入库,同时又频繁的查询和修改,我们考虑使用memory, 速度极快.

3)操作
1、创建表时指定存储引擎
Create table 表名(字段列表) engine 存储引擎名称;
在这里插入图片描述
注意:如果不指定则使用默认的存储引擎,这个默认实在my.ini配置
在这里插入图片描述
2、修改存储引擎:
alter table table_name engine=innodb;

4.2.索引
4.2.1.引入

说起提高数据库性能,索引是最物美价廉的东西了。不用加内存,不用改程序,不用调sql,只要执行个正确的‘create index’,查询速度就可能提高百倍千倍,这可真有诱惑力。可是天下没有免费的午餐,查询速度的提高是以插入、更新、删除的速度为代价的,这些写操作,增加了大量的I/O。
以空间换时间

4.2.2.什么是索引-原理

索引(Index)是帮助DBMS高效获取数据的数据结构。
组织数据方式,及访问数据的api的封装。-list,set,map,数组
1)索引查找
没有使用索引
使用索引
在这里插入图片描述

2)索引算法
Mysql常用引擎允许的索引类型
在这里插入图片描述
FullText全文索引算法,myisam,只能能在char vachar text
hash就像Map,通过一个key直接就能找到value
B-tree算法

  1. 小结
    总结:使用索引把全表查找变为索引查找,减少查询次数,增加查询效率。而索引查找效率的取决于索引算法。也就是索引(Index)是帮助DBMS高效获取数据的数据结构
4.2.3.操作

mysql中索引的分类: 按照字段是否唯一或为null

  • 普通索引:允许重复的值出现,可以在任何字段上面添加
  • 唯一索引:除了不能有重复的记录外,其它和普通索引一样,可以在值是唯一的字段添加(用户名、手机号码、身份证、email,QQ),可以为null,并且可以有多个null
  • 主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
  • 全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyISAM有用

一般不用,默认只支持英文. -使用ES,Lucene代替就ok

1)添加
分类:普通索引/唯一索引/主键索引/全文索引
普通索引:允许重复的值出现
一般来说,普通索引的创建,是先创建表,然后在创建普通索引
 create index 索引名 on 表 (列1,列名2,…);
 alter table 表名add index 索引名(列1,列名2,…);
 比如:
  create table aaa(id int unsigned,name varchar(32));
  create index nameIndex on aaa(name);
  alter table aaa add index index1(name);

唯一索引:除了不能有重复的记录外,其它和普通索引一样

1、当表的某列被指定为unique约束时,这列就是一个唯一索引
 例如:create table bbb(id int primary key auto_increment , name varchar(32) unique);
 这时, name 列就是一个唯一索引.
2、在创建表后,再去创建唯一索引
 create unique index 索引名 on 表名 (列1,列2,…);
 alter table 表名add unique index 索引名 (列1,列2,…);
 例如:
  create table ccc(id int primary key auto_increment, name varchar(32));

注意:unique字段可以为NULL,并可以有多NULL, 但是如果是具体内容,则不能重复.
主键字段,不能为NULL,也不能重复.

主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
1、创建表时指定主键
 例如:

create table ddd(id int unsigned primary key auto_increment ,name varchar(32) not null  defaul ‘’);

这时id 列就是主键索引.
2、如果你创建表时,没有指定主键,也可以在创建表后,再添加主键。
 指令:alter table 表名 add primary key (列名);
 举例:

create table eee(id int , name varchar(32) not null default ‘’);
     alter table eee add primary key (id);

全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyISAM有用

1、创建表时定义:

CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT,
       FULLTEXT (title,body)
     )engine=myisam charset utf8;

INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');

创建表完成后定义

    create fulltext index 索引名 on 表名(1,2);
    alter table 表名add fulltext index 索引名 (1,2);
        比如:
     CREATE TABLE articles (
       id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
       title VARCHAR(200),
       body TEXT
     )engine=myisam charset utf8;

    Alter table article add fulltext index title_body_fulltext_index(title,body);

    INSERT INTO articles (title,body) VALUES
     ('MySQL Tutorial','DBMS stands for DataBase ...'),
     ('How To Use MySQL Well','After you went through a ...'),
     ('Optimizing MySQL','In this tutorial we will show ...'),
     ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
     ('MySQL vs. YourSQL','In the following database comparison ...'),
     ('MySQL Security','When configured properly, MySQL ...');

用法:
错误用法:
explain select * from articles where body like ‘%mysql%’; 【不会使用到全文索引】
在这里插入图片描述
正确用法::
explain select * from articles where match(title,body) against(‘database’);【会使用全文索引】
在这里插入图片描述

2) 查询
show index(es) from 表名

3) 删除
alter table 表名 drop index 索引名;
alter table 表名 drop primary key 删除主键。 [主键定义为auto_increment时不能删除]

4) 修改
先删除后添加=修改

4.2.4.注意事项

索引的代价:
1.占用磁盘空间。
2.对dml操作有影响,因为要维护索引,变慢。

  • 在哪些列上适合添加索引?
    较频繁的作为查询条件字段应该创建索引
    select * from emp where empno = 1 ename
    唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
    select * from emp where sex = '男’
    更新非常频繁的字段不适合创建索引
    select * from emp where logincount = 1
  • 总结: 满足以下条件的字段,才应该创建索引.
    a: 肯定在where条件经常使用 或者经常用来排序 order by后面的字段
    b: 该字段的内容不是唯一的几个值(sex)
    c: 字段内容不是频繁变化.
    不会出现在WHERE子句中字段不该创建索引

经常查询 很少修改 唯一性不要太差

4.2.5.小技巧 了解,一般不会问到

根据索引列的多少分为复合索引和普通索引
普通索引(单列索引):该索引只在一个列上面创建
复合索引(多列索引):该索引只在多个列上面创建

1)对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。
alter table dept add index my_indx (dname,loc); // dname 左边的列,loc就是 右边的列
explain select * from dept where dname=‘aaa’\G 会使用到索引
在这里插入图片描述
explain select * from dept where loc=‘aaa’\G 就不会使用到索引
在这里插入图片描述

  1. 对于使用like的查询,查询如果是%aaa’不会使用到索引而‘aaa%’会使用到索引。
    explain select * from dept where dname like ‘%aaa’\G不能使用索引
    在这里插入图片描述
    explain select * from dept where dname like ‘aaa%’\G使用索引.
    在这里插入图片描述

所以在like查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面有变化的值,则考虑使用 全文索引->lucene或Es

3.如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须单独使用时能使用索引. 全部能够单独使用才能使用

explain select * from dept where dname = 'aaa';
explain select * from dept where loc = 'aaa';
select * from dept where dname=’xxx’ or loc=’xx’;

4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。
expain select * from dept where dname=’111’;
在这里插入图片描述
expain select * from dept where dname=111;(数值自动转字符串)
在这里插入图片描述
expain select * from dept where dname=qqq;报错
也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来.
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引。
表里面只有一条记录

4.3.SQL优化小技巧

https://www.jb51.net/article/35655.htm
SQL:ddl dml dql

4.3.1.DDL优化 批量插入

1 、通过禁用索引来提供导入数据性能 。 这个操作主要针对有数据库的表,追加数据

//去除键
alter table test3 DISABLE keys;
//批量插入数据
insert into test3 select * from test;
//恢复键
alter table test3 ENABLE keys;

变多次索引维护为一次索引维护

2、 关闭唯一校验

set unique_checks=0  关闭
//批量插入数据
insert into test3 select * from test;
set unique_checks=1  开启

变多次唯一校验为一次唯一校验

3、修改事务提交方式(导入)

set autocommit=0   关闭
//批量插入
set autocommit=1   开启

变多次事务提交为一次事务提交

4.3.2.DML优化 批量插入
insert into test values(1,2);
insert into test values(1,3);
insert into test values(1,4);
//合并多条为一条
insert into test values(1,2),(1,3),(1,4)

变多次事务提交为一次事务提交

4.3.3.DQL优化
  • 1) order by优化
    1、多用索引排序
    2、普通结果排序(非索引排序)Filesort
    索引本身就是排序的,所以多使用索引。 如果某字段要排序,可以创建索引来提高效率

  • 2)or优化
    在两个独立索引上使用or的性能优于
    1、 or两边都是用索引字段做判断,性能好!!
    2、 or两边,有一边不用,性能差
    3、 如果employee表的name和email这两列是一个复合索引,但是如果是 :name=‘A’ OR email=‘B’ 这种方式,不会用到索引!

30种sql语句优化
https://www.cnblogs.com/Little-Li/p/8031295.html
sql语句的执行顺序
from where having group by select order by limit

  • 3)小表驱动大表
1.’对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
4.应尽量避免在 where 子句中使用 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.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
若要提高效率,可以考虑全文检索。
6.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num
8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2
9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(...)
13.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
30.尽量避免大事务操作,提高系统并发能力。

作业把这五点理解并抄一遍.

5.优化2-多机优化-分布式系统理论介绍

5.1. 什么是分布式系统

一般认为:“一个分布式系统是一些独立的网络计算机集合,但是对这个系统的用户来说,系统就像一台网络计算机一样。”这个定义有两方面的含义:第一,从硬件角度来讲,每台网络计算机都是自主的;第二,从软件角度来讲,用户将整个系统看做是一台网络计算机。这两者都是必需的,缺一不可。

微服务架构
数据库集群 主从同步-也是分布式集群

5.2.CAP理论-多台服务器
5.2.1.CAP是什么
Consistency(一致性): 性能比较低
一致性是指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上,从任意结点读取到的据都是最新的状态。
如何实现一致性?
1、写入主节点后要将数据同步到从节点。
2、 写入主节点,要将从节点同步期间要将从节点锁定,待同步完成后再释放锁,以免在新数据写入功后,向从从节点查询到旧的数据。
分布式系统一致性的特点:
1、由于存在节点同步的过程,写操作的响应会有一定的延迟。
2、为了保证数据一致性会对资源暂时锁定 ,待数据同步完成释放锁定资源。
3.如果请求数据同步失败的结点则会返回错误信息, -定不会返回旧数据。

Availability(可用性):
可用性是指任何操作都可以得到响应结果,且不会出现响应超时或响应错误。
如何实现可用性?
1、写入主节点后要将数据同步到从节点。
2、由于要保证从节点的可用性,不可将从节点中的资源进行锁定。
3、即时数据还没有同步过来,从节点也要返回要查询的数据,哪怕是旧数据,如果连旧数据也没有则可以约定返回一个默认信息,但不能返回错误或响应超时。
分布式系统可用性的特点:
1、所有请求都有响应,且不会出现响应超时或响应错误。

     Mysql集群 返回一个老数据 

Partition tolerance(分区容忍性) 可靠性

通常分布式系统的各结点部署在不同的子网,这就是网络分区,不可避免的会出现由于网络问题而导致结点之间通信失败,此时仍可对外提供服务,这叫分区容忍性。
如何实现分区容忍性?
1、尽量使用异步取代同步操作,例如使用异步方式将数据从主节点同步到从数据,这样结点之间能有效的实现松耦合。
2、添加从节点结点,其中一个从结点挂掉其它从结点提供服务。
分布式分区容忍性的特点:
1、分区容忍性分是布式系统具备的基本能力。

    多个节点
5.2.2.常见组合

定理:任何分布式系统只可同时满足二点,没法三者兼顾。
忠告:架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。
在这里插入图片描述
(1)满足CA舍弃P,也就是满足一致性和可用性,舍弃容错性。但是这也就意味着你的系统不是分布式的了,因为涉及分布式的想法就是把功能分开,部署到不同的机器上。单个mysql服务器

(2)满足CP舍弃A,也就是满足一致性和容错性,舍弃可用性。如果你的系统允许有段时间的访问失效等问题,这个是可以满足的。就好比多个人并发买票,后台网络出现故障,你买的时候系统就崩溃了。 redis.set(key,value) 当我在进行操作的时候其他的要进行等待或者超时异常
Redis zk consol nacas

(3)满足AP舍弃C,也就是满足可用性和容错性,舍弃一致性。这也就是意味着你的系统在并发访问的时候可能会出现数据不一致的情况。 Mysql主从同步 eureaka

一般来说,现在的分布式系统都要支持p,只能选择c或者a中的一个,如果数据要求立即生效,选择c,否则运行一定的延迟a。

Cp ap

5.3.BASE理论

1、理解强一致性和最终一致性
CAP理论告诉我们一个分布式系统最多只能同时满足一致性( Consistency)、可用性( Availability )和分区容忍性( Partition tolerance )这三项中的两项,其中AP在实际应用中较多, AP即舍弃一致性,保证可用性和分区容忍性,但是在实际生产中很多场景都要实现最终一致性,比如前边我们举的例子主节点向从节点同步数据,即使不要一致性,但是最终也要将数据同步成功来保证数据一致,这种一致性和CAP中的一致性不同, CAP中的一致性要求在任何时间查询每个结点数据都必须一致,它强调的是强一致性,但是最终一致性是允许可以在一段时间内每个结点的数据不一致,但是经过一段时间每个结点的数据必须一致,它强调的是最终一致性。

(1)强一致性
对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。比如小明更新V0到V1,那么小华读取的时候也应该是V1。
(2)弱一致性
如果能容忍后续的部分或者全部访问不到,则是弱一致性。比如小明更新VO到V1,可以容忍那么小华读取的时候是V0。
(3)最终一致性
如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。比如小明更新VO到V1,可以使得小华在一段时间之后读取的时候是V1。

为了保证分布式系统的可用性,牺牲强一致性,采用最终一致性。

2 Base理论
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent (最终一致性)三个短语的缩写。BASE理论是对CAP中AP的一个扩展,通过牺牲强一致性来获得可用性,当出现故障允许部分不可用但要保证核心功能可用,允许数据在一段时间内是不一致的,但最终达到一致状态。满足BASE理论的事务,我们称之为"柔性事务"。
●基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用。如,电商网站交易付款出现问题了,商品依然可以正常浏览。
●软状态:由于不要求强一致性,所以BASE允许系统中存在中间状态(也叫软状态) ,这个状态不影响系统可用性,如订单的"支付中"、“数据同步中”等状态,待数据最终一致后状态改为“成功”状态。
●最终一致:最终一致是指经过一段时间后,所有节点数据都将会达到一致。如订单的"支付中"状态,最终会变为“支付成功”或者"支付失败" ,使订单状态与实际交易结果达成-致,但需要一定时间的延迟等待。

操作我时其他可用,但是有中间状态,但是要最终一致性。

p一定要满足,c和a二选1,ap用得最多,但是我们还要使用base理论来完成最终一致性

6.优化2-多机优化-集群

分布式: 不同的服务分散到不同节点. 第一种:web,db 第二种:课程服务,用户服务
集群: 同一个服务通过多态服务器来处理. 第一种:db集群 web集群 第二种:课程服务集群 用户服务
集群

6.1. DB集群
6.1.1. 为什么要集群

高并发需求: 500W并发
可用性:单点故障

6.1.2. 集群方案-同一个库集群

集群:多个服务器一起对外提供一个服务。是一种特殊分布式。
在这里插入图片描述

6.2.集群
6.2.1.主从同步-mysql自己提供

在这里插入图片描述

5.1.1准备环境

至少需要两台服务器,以后肯定是独立两台电脑,当然也可以使用虚拟机. 教学的时候,可以安装多个服务(使用不同的端口)来代替服务器.
1)分别构造主、从数据库并输出日志(方便定位问题)
拷贝
改端口
在这里插入图片描述
拷贝数据
拷贝原理数据库的datadir mysql到模拟的主从数据库
在这里插入图片描述
配置日志路径

2)安装及启动:
修改master中的my.ini 路径改为master的路径
mysqld --install MySQLXY --defaults-file=“C:\Program Files\MySQL\MySQL Server X.Y\my.ini”
(install/remove of the service denied 权限不足 以管理身份运行)
net start MySQLXY
Sc delete master/slave 弄错了可以删除服务重新操作
开启日志(非必须)

(非必须)开启sql语句的日志,生产环境不建议开启:

查看日志目录,并开启sql语句的日志:

mysql>show variables like ‘%general_log%’;
mysql>set global general_log=on;
开启后,重启Mysql ,上述开启日志配置将失效。
在这里插入图片描述
测试

5.1.2.master服务器配置

1)修改master方的mysql.ini

 log-bin=mysql-bin
 server-id=1
 innodb_flush_log_at_trx_commit=1
 sync_binlog=1
 binlog_ignore_db=mysql
 binlog_checksum=none

2)重启master服务,登录
在这里插入图片描述

3)授权savle服务器的使用的账号及权限

场景:
            	master主服务器: 192.168.1.101
                slave从服务器     :  192.168.1.102
          1) 授权给slave数据库服务器192.168.10.131(master用户,只对slave服务器开放)
              语法为:GRANT REPLICATION SLAVE ON *.* to '用户名'@'192.168.0.102' identified 
                      by ‘密码’; 
               Mysql>  GRANT REPLICATION SLAVE ON *.* to 'lvtest'@'192.168.77.128'identified 
                       by 'admin';
                       参数说明:
                                lvtest:slave连接master使用的账号
                                IDENTIFIED BY 'admin' :slave连接master使用的密码
                                192.168.77.128:slave IP
              
           2)查询主数据库状态
	 		    Mysql> show master status;
          +--------------------+----------+---------------+------------------------------+
          | File                            | Position  | Binlog_Do_DB | Binlog_Ignore_DB |
          +--------------------+----------+---------------+------------------------------+
          | mysql-bin.000002  | 226          |                          |       mysql   |
          +--------------------+----------+---------------+------------------------------+
           记录 File  和 Position的值,在slave端使用
5.1.3 slave配置

1、修改slave服务器的配置文件my.ini将 server-id = 1修改为 server-id = 10,并确保这个
ID没有被别的MySQL服务所使用。
2、启动slave服务器,登录
3、在slave端,配置master链接信息 (执行语句)

       1) 配置
        Mysql>  change master to
               master_host='192.168.77.1',   #master IP
               master_user='lvtest',          #master数据库通过GRANT授权的账号
               master_password='admin',         #master数据库通过GRANT授权的密码
               master_port=3307,              #master数据库的密码
               master_log_file='mysql-bin.000001', 
                          #master数据库中通过show master status显示的File名称
               master_log_pos=296         
                           #master数据库的通过show master status显示的Position的值
        2) (重启)连接
        Mysql> start slave;

        3)主从同步检查
        show slave status;
        其中Slave_IO_Running 与 Slave_SQL_Running 的值都必须为YES,才表明状态正常。

4、 测试

      1) 在master上,建库、建表、添加数据
      2) 刷新slave库,记录也存在

由此,整个MySQL主从复制的过程就完成了,接下来,我们进行MySQL读写分离的安装与配置。

6.2.2.读写分离-sharding-jdbc

明天一起讲

7.课程总结

7.1.重点

1.定位慢查询
2.优化

7.2.难点

1.优化

7.3.如何掌握?

1.勤加练习…
2.学会看说明手册

7.4.排错技巧(技巧)

8.课后练习

1.测试数据库优化部分

9.面试题

1.有没有做过数据库优化

10.扩展知识或课外阅读推荐(可选)

10.1.扩展知识
10.2.课外阅读

读写分离延迟

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值