数据库mysql性能优化-学习笔记

数据库mysql性能优化

    • 1. 数据库设计范式
    • 2. 常见关系数据库
    • 3. MySQL 的版本
    • 4. mysql存储计划
    • 5 . mysql查询配置 和 设置配置
    • 6 . mysql基本参数
    • 7 .mysql设计优化
    • 8.mysql事务
    • 9.锁
    • 10 .数据库的隔离级别
    • 11 . 撤销日志:undo log,重做日志: redo log
    • 12 . show engine innodb status查看innodb事务状态
    • 13 . set autocpmmit=0;关闭自动事务
    • 14 . 当数据量增大,查询变慢该如何给出解决方案?
    • 15.索引的存储结构:
    • 16.为什么主键比索引的查询要快:
    • 17.修改表结构的危害:
    • 18. 大数据写入优化:
    • 19. 数据更新:
    • 20. 模糊查询:
    • 21 . 索引失效汇总:
    • 22. 索引优化:
    • 23. 怎么实现主键 ID 还有没有其他办法?
    • 24. 高效分页
    • 25. 单机 MySQL 数据库的几个问题 还有没有其他问题?
    • 25.mysql高可用的几种方案:

1. 数据库设计范式

  注意:范式只是早期大佬们提出的规范,现在很多情况下,为了性能基本都不遵守基本规范,了解即可。具体原因,以前的提出范式的时候,磁盘的存储是相当贵的,当时是为了节省空间,从而牺牲时间,而如今,很多公司都基本为了追求性能,为了时间而牺牲空间,比如:为了查询更加迅速,会去进行单表冗余,此时就违反了第二范式

第一范式(1NF): 关系 R 属于第一范式,当且仅当 R 中的每一个属性 A 的值域只包含原子项,
      意思: 每个列不能进一步被拆分,例如 某列:经济系王强 不满足,可拆分经济系,王强
第二范式(2NF):在满足 1NF 的基础上,消除非主属性对码的部分函数依赖
      意思: 每个表都有主键,且非主键列要与主键相关
第三范式(3NF):在满足 2NF 的基础上,消除非主属性对码的传递函数依赖
      意思: 消除传递依赖,即,列要与主键依赖关系
BC 范式(BCNF):在满足 3NF 的基础上,消除主属性对码的部分和传递函数依赖
第四范式(4NF):消除非平凡的多值依赖
第五范式(5NF):消除一些不合适的连接依赖

2. 常见关系数据库

开源:MySQL、PostgreSQL
商业:Oracle,DB2,SQL Server

内存数据库:Redis?,VoltDB
图数据库:Neo4j,Nebula
时序数据库:InfluxDB、openTSDB
其他关系数据库:Access、Sqlite、H2、Derby、Sybase、Infomix 等
NoSQL 数据库:MongoDB、Hbase、Cassandra、CouchDB
NewSQL/分布式数据库:TiDB、CockroachDB、NuoDB、OpenGauss、OB、TDSQ

3. MySQL 的版本

  • 4.0支持 InnoDB,事务
  • 2003年,5.0 - 5.6 ==> 历史使用最多的版本
  • 5.7 ==> 近期使用最多的版本
  • 8.0 ==>最新和功能完善的版

- 5.6/5.7的差异 :

  • 多主
  • MGR 高可用
  • 分区表
  • json
  • 性能
  • 修复 XA

- 5.7/8.0的差异:

  • 通用表达式 CTE
  • 窗口函数
  • 持久化参数
  • 自增列持久化
  • 默认编码 utf8mb4 J精确地utf8
  • DDL 原子性
  • JSON 增强
  • 不再对 group by 进行隐式排序??==> 坑

4. mysql存储计划

  注意:存储计划,现在很少用了,因为存储计划不适用于项目的迁移,比如:公司维护了一套几年的业务系统用的mysql数据库,并写了大量的存储计划。但是,现在系统做升级,换库,则mysql的存储计划将不能迁移,产生大量的迁移工作。

-- 创建存储过程
CREATE PROCEDURE userData(
    IN a VARCHAR(256)
)
BEGIN
    SELECT * from tbl_area WHERE id = a;
END;


-- 销毁存储过程
drop procedure userData;


-- 调用存储过程
call userData(310101000000)

5 . mysql查询配置 和 设置配置

-- 查询当前配置
show variables like '%last%'

-- 查询全局配置
show global variables like '%innodb%';

-- 查询某个变量属性
select @@last_insert_id;

-- 设置属性
set last_insert_id = 1-- 设置全局属性,注意5.6/5.7的mysql 重启后全局设置不生效
set global last_insert_id = 1

6 . mysql基本参数

1)连接请求的变量
  1、max_connections 最大连接数
  2、back_log 半连接状态最大数量
  3、wait_timeout和interative_timeout 等待超时时间和交互超时时间

2)缓冲区变量
  4、key_buffer_size
  5、query_cache_size(查询缓存简称 QC) 8.0以后没有这个参数
  6、max_connect_errors 最大错误数
  7、sort_buffer_size 1M
 &emsp**;8、max_allowed_packet=32M 给mysql的最大数据包:如,sql语句超过32M,则拒收**
  9、join_buffer_size=2M
  10、thread_cache_size=30

3)配置 Innodb 的几个变量
  11、innodb_buffer_pool_size=128M 缓存区域大小
  12、innodb_flush_log_at_trx_commit
  13、innodb_thread_concurrency=0
  14、innodb_log_buffer_size
  15、innodb_log_file_size=50M
  16、innodb_log_files_in_group=3
  17、read_buffer_size=1M 读取数据时Buffer大小
  18、read_rnd_buffer_size=16M 随机读Buffer大小
  19、bulk_insert_buffer_size=64M 插入的时候buffer的大小
  20、binary log

7 .mysql设计优化

  • 如何恰当选择引擎?
    不要强事务,数据量比较大,比如论坛这种,可以用mysISAM,
    做电商,金融,这种强事务的情况下,可以用Innodb。
    数据小,不需要持久化,可以用memory
    数据要归档,可以使用 toku,压缩效率高,

  • 库表如何命名?
    用前缀表示模块

  • 如何合理拆分宽表?

  • 如何选择恰当数据类型:明确、尽量小

  • char、varchar 的选择
    char是定长,varchar是变长的

  • (text/blob/clob)的使用问题?
    数据量比较大,存储的一条数据的时候会操作两次,第一次插入其他列,第二次打开updload上传流,效率低

  • 文件、图片是否要存入到数据库?
    不建议存在数据库中,建议文件图片或者大的数据类型blob这种文本很长的的,可以放在分布式文件系统上,或者应用服务器磁盘上,数据库里放url

  • 时间日期的存储问题?

  • 数值的精度问题?

  • 是否使用外键、触发器
    -唯一约束和索引的关系?
    唯一约束自动上索引

  • 是否可以冗余字段?
    提高查询效率

  • 是否使用游标、变量、视图、自定义函数、存储过程?
    不建议使用,不容易移植

  • 自增主键的使用问题?
    数据量大的情况,分布式的情况 不建议使用

  • 能够在线修改表结构(DDL 操作)?
    在线修改,导出的时候,会进行锁表

  • 逻辑删除还是物理删除?
    建议逻辑删除

  • 要不要加 create_time,update_time 时间戳?
    建议加

  • 数据库碎片问题?
    进行操作会进行锁表,空闲时间做

  • 如何快速导入导出、备份数据?
    弄个主从数据库,备份的时候直接摘下来从库,进行备份从库,
    导出的,时候,先导数据,后建立索引

8.mysql事务

•Atomicity: 原子性,一次事务中的操作要么全部成功,要么全部失败。
•Consistency: 一致性,跨表、跨行、跨事务,数据库始终保持一致状态。
•Isolation: 隔离性,可见性,保护事务不会互相干扰,包含4种隔离级别。
•Durability: 持久性,事务提交成功后,不会丢数据。如电源故障,系统崩溃

9.锁

for update 上 排他锁(X锁),lock in share model 上共享锁(S锁)
数据库mysql性能优化-学习笔记_第1张图片

行级锁(InnoDB)
•记录锁(Record): 始终锁定索引记录,注意隐藏的聚簇索引
•间隙锁(Gap): 锁住一个范围
•临键锁(Next-Key): 记录锁+间隙锁的组合; 可“锁定”表中不存在记录
•谓词锁(Predicat): 空间索引

死锁: -阻塞与互相等待 -增删改、锁定读 -死锁检测与自动回滚 -锁粒度与程序设计
\

10 .数据库的隔离级别

  • 读未提交: READ UNCOMMITTED 很少使用
  • 读已提交(RC): READ COMMITTED :oracle,sql server,db2默认的
  • 可重复读(RR): REPEATABLE READ :mysql默认的
  • 可串行化: SERIALIZABLE 事务隔离是数据库的基础特征。

MySQL:
  • 可以设置全局的默认隔离级别
  • 可以单独设置会话的隔离级别
  • InnoDB 实现与标准之间的差异 隔离级别 并发性 可靠性 一致性

  •脏读(dirty read) : 使用到从未被确认的数据(例如: 早期版本、回滚),其他线程还没提交的数据,被查询到了
  •不可重复读(unrepeated read): 不加锁的情况下,其他事务 update 会对结果集有影响 ,查询到的结果集被其他线程修改
  •幻读(phantom read): 相同的查询语句,在不同的时间点执行时,产生不同的结果集不同,两次查询结果不一致
  --解决:加锁,提高隔离级别

11 . 撤销日志:undo log,重做日志: redo log

undo log: 撤消日志
  •保证事务的原子性
  •用处: 事务回滚, 一致性读、崩溃恢复。
  •记录事务回滚时所需的撤消操作
  •一条 INSERT 语句,对应一条 DELETE 的 undo log
  •每个 UPDATE 语句,对应一条相反 UPDATE 的 undo log 保存位置:
  •system tablespace(MySQL 5.7 默认)
  •undo tablespaces(MySQL 8.0 默认)

redo log: 重做日志
  •确保事务的持久性,防止事务提交后数据未刷新到磁盘就掉电或崩溃。
  •事务执行过程中写入 redo log,记录事务对数据页做了哪些修改。
  •提升性能: WAL(Write-Ahead Logging) 技术,先写日志,再写磁盘。
  •日志文件: ib_logfile0, ib_logfile1
  •日志缓冲: innodb_log_buffer_size
  •强刷: fsync()

–mvcc机制,事务控制的隐藏列配合undo log 进行回滚,可查询
  

12 . show engine innodb status查看innodb事务状态

  

13 . set autocpmmit=0;关闭自动事务

  

14 . 当数据量增大,查询变慢该如何给出解决方案?

  系统经过一个月的运行,用户表增长约100万,DBA 接到告警, CPU 升高,查询越来越慢,请定位问题并给出解决方案:

-慢查询日志
   Slowlog文件,

-看应用和运维的监控

  

15.索引的存储结构:

• Hash
  计算hash值,kv存储
• B-Tree/ B+Tree
  B树:按块存储,每块有指针和数据,指针指向其他块
  B+树:分级别,最多存储三级,做三次io转换,与B树不同的是,所有数据都在最底层的叶子节点中,上层父节点只有键值和指针。所有叶子节点的块都会用双向指针串起来,第二次调用时,不用回溯树结构

  

16.为什么主键比索引的查询要快:

  因为数据库b+树存储数据规则时,是主键直接对应着数据,聚合索引, 而非主键索引,称二级索引是单独创建的索引文件,不包含实际数据,需要找到主键去再回表拿记录

  

17.修改表结构的危害:

– 会锁表, 占用表
– 会重建索引
– 主从模式会延迟主从同步
– 抢占资源
  

18. 大数据写入优化:

– 采用 Multiple Values/Add Batch的方式在后面追加
– load data 命令导入csv文件
– PreparedStatement 减少 SQL 解析
– 索引和约束问题 最后数据导入之后在重建
  

19. 数据更新:

数据范围的更新设计到 锁
注意 GAP Lock 的问题,能不用范围更新就不用,要精确,否则会导致锁区域
导致锁的范围变大

–精确
  

20. 模糊查询:

like 参数尽量 (百分号在后面)l% 前置查询会调用索引, %l 百分号在前面则不会走索引

使用like的数据比较多,组合模糊查询,倒排索引 建议使用 solr、es

  

21 . 索引失效汇总:

  NULL, not , not in ,函数等;
  or也会使索引失效,减少使用or ,可以用 union(去重) 和union all(union all 不去重),替换
  

22. 索引优化:

  - 什么时候使用索引?
     - 字段有唯一限制时,如商品编码
     - 经常用来条件查询的如WHERE后的查询
     - 经常用于group byorder by 的字段
  
  - 什么时候不要创建索引?
     - 字段中大量重复字段,字段数据太大
     - 经常更新的字段,避免为何索引成本太高
  

23. 怎么实现主键 ID 还有没有其他办法?

  • 自增
  • sequence
  • 模拟 seq
  • UUID
  • 时间戳/随机数
  • snowflake 雪花算法,现在用的比较多
      

24. 高效分页

  高效分页 还能不能继续改进?
  - 分页:count/pageSize/pageNum, 带条件的查询语句
  - 常见实现-分页插件:使用查询 SQL,嵌套一个 count,性能的坑?
  - 改进一下1,重写 count - 大数量级分页的问题,limit 100000,20
  - 改进一下2,反序
  - 继续改进3,技术向:带 id
      例如:select * from city where id>20 limit 20
  - 继续改进4,需求向:非精确分页
  - 所有条件组合? 索引
  
  

25. 单机 MySQL 数据库的几个问题 还有没有其他问题?

随着数据量的增大,读写并发的增加,系统可用性要求的提升,
单机 MySQL 面临:
1、容量有限,难以扩容
2、读写压力,QPS 过大,特别是分析类需求会影响到业务事务
3、可用性不足,宕机问题

  
  

25.mysql高可用的几种方案:

– MySQL 高可用0:

主从手动切换 如果主节点挂掉,将某个从改成主;
重新配置其他从节点。
修改应用数据源配置。

>有什么问题?

  1. 可能数据不一致。
  2. 需要人工干预。
  3. 代码和配置的侵入性

– MySQL 高可用1:
主从手动切换 用 LVS+Keepalived 实现多个节点的探活+请求路由。
配置 VIP 或 DNS 实现配置不变更。

> 有什么问题?

  1. 手工处理主从切换
  2. 大量的配置和脚本定义

– MySQL 高可用2:MHA
MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由 日本 DeNA 公司的 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。

基于 Perl 语言开发,一般能在30s内实现主从切换。 切换时,直接通过 SSH 复制主节点的日志。

> 有什么问题?

  1. 需要配置 SSH 信息
  2. 至少3台

– MySQL 高可用3:MGR
如果主节点挂掉,将自动选择某个从改成主; 无需人工干预,基于组复制,保证数据一致性。

> 有什么问题?

  1. 外部获得状态变更需要读取数据库。
  2. 外部需要使用 LVS/VIP 配置。

– MySQL 高可用4:MySQL Cluster

– MySQL 高可用5:Orchestrator
如果主节点挂掉,将某个从改成主;
Orchestrator 一款 MySQL 高可用和复制拓扑管理工具,支持复制拓扑结构的调整,自动故障转移和手动主从切换等。 后段数据库 MySQL 或 SQLite 存储元数据,并提供 Web 界面展示 MySQL 复制的拓扑关系及状态, 通过 Web 可更改 MySQL 实例的复制关系和部分配置信息,同时也提供命令行和 API 接口,方便运维 管理。

特点:

  1. 自动发现 MySQL 的复制拓扑,并且在 Web 上展示;
  2. 重构复制关系,可以在 Web 进行拖图来进行复制关系变更;
  3. 检测主异常,并可以自动或手动恢复,通过 Hooks 进行自定义脚本;
  4. 支持命令行和 Web 界面管理复

你可能感兴趣的:(mysql优化)