mysql数据库sql优化及ACID和事务的隔离级别

数据库相关知识

1.如何优化sql

1. 硬件和操作系统层面的优化

​ 影响Mysql性能的因素有,CPU、可用内存大小、磁盘读写速度、网络带宽

从操作系层面来说,应用文件句柄数、操作系统网络的配置都会影响到Mysql性能

2. 架构设计层面的优化

​ 搭建主从集群,保证高可用性

​ 读写分离设计 在读多写少的情况下避免读写冲突导致的性能影响

​ 分库分表 分库可以降低单个服务器的压力,分表可以降低单个表的数据量

​ 针对热点数据进行缓存

3. mysql程序配置优化
  1. 调整 InnoDB 缓冲池大小

    --  innodb_buffer_pool_size:设置为可用内存的 70%-80%,以提高数据缓存能力。
    SET GLOBAL innodb_buffer_pool_size = SIZE_IN_BYTES;
    
  2. 调整查询缓存

    -- query_cache_size 和 query_cache_type:设置查询缓存大小和类型。注意,MySQL 8.0 已经废弃了查询缓存功能。
    SET GLOBAL query_cache_size = SIZE_IN_BYTES;
    SET GLOBAL query_cache_type = 1;  -- 0: 禁用, 1: 启用
    
  3. 调整连接和线程相关参数

    max_connections:增加最大连接数以支持更多并发连接。
    thread_cache_size:设置线程缓存大小以减少线程创建开销。
    
  4. 调整日志和缓冲

    innodb_log_file_size 和 innodb_log_buffer_size:调整 InnoDB 日志文件大小和日志缓冲区大小。
    
4. 索引失效
  1. 索引上进行函数运算

    -- 索引失效
    SELECT * FROM employees WHERE YEAR(hire_date) = 2022;
    
    -- 索引有效
    SELECT * FROM employees WHERE hire_date BETWEEN '2022-01-01' AND '2022-12-31';
    
  2. 索引使用用的类型不匹配,会隐式转换类型导致索引失效

    -- hire_date 是 DATE 类型,'2022-01-01' 是字符串类型
    -- 隐式类型转换导致索引失效
    SELECT * FROM employees WHERE hire_date = '2022-01-01';
    
    -- 正确使用
    SELECT * FROM employees WHERE hire_date = DATE('2022-01-01');
    
  3. 使用!=或者not 查询 此时索引效率非常低,因此mysql判断不走索引

    -- 索引失效
    SELECT * FROM employees WHERE salary != 5000;
    
    -- 索引有效
    SELECT * FROM employees WHERE salary > 5000 OR salary < 5000;
    
  4. 使用or的时候,or的前后都得使用索引,否则索引失效

    -- 假设 name 列有索引,department 列无索引
    -- 索引失效
    SELECT * FROM employees WHERE name = 'John' OR department = 'HR';
    
    -- 索引有效
    -- 假设 name 和 department 列都有索引
    SELECT * FROM employees WHERE name = 'John' OR department = 'HR';
    
  5. 组合索引需要匹配最左原则(查询条件需要跟索引的顺序一样)

    -- 假设有组合索引 (name, age)
    -- 索引失效
    SELECT * FROM employees WHERE age = 30;
    
    -- 索引有效
    SELECT * FROM employees WHERE name = 'John' AND age = 30;
    
    -- 索引部分有效,只用到 name 部分
    SELECT * FROM employees WHERE name = 'John';
    
  6. 使用like 百分号放在左边时会失效

    -- 假设 name 列有索引
    -- 索引失效
    SELECT * FROM employees WHERE name LIKE '%ohn';
    
    -- 索引有效
    SELECT * FROM employees WHERE name LIKE 'John%';
    
5. sql优化

​ 1.慢sql定位:通过慢sql查询日志或者日志分析工具得到有问题的sql列表

​ 2.使用explain 查看sql的执计划,重点关注type key rows filterd字段,执行慢的根本原因

​ 3.使用show profile工具 可以得到sql的资源使用 io,cpu、内存的使用情况

​ l SQL的查询一定要基于索引来进行数据扫描

​ l 避免索引列上使用函数或者运算,这样会导致索引失效

​ l where 字句中like %号,尽量放置在右边

​ l 使用索引扫描,联合索引中的列从左往右,命中越多越好.

​ l 尽可能使用SQL语句用到的索引完成排序,避免使用文件排序的方式

​ l 查询有效的列信息即可.少用 * 代替列信息

​ l 永远用小结果集驱动大结果集。

2.事务的隔离级别

名词解释

  1. 脏读(Dirty Read)

    定义: 脏读是指一个事务读取了另一个事务尚未提交的数据。如果那个事务回滚了,那么第一个事务读取的数据就是无效的或错误的。

    **示例:**
    假设有两个事务 A 和 B。
    
    - 事务 A 更新了数据但还未提交。
    - 事务 B 读取了事务 A 尚未提交的数据。
    - 如果事务 A 最终回滚,那么事务 B 读取的数据将是错误的。
    
    总结
    事务A读取到事务B未提交的数据 事务B回滚 导致事务A读取的数据无效 即为脏读
    
  2. 不可重复读(Non-repeatable Read)

    定义: 不可重复读是指在一个事务中多次读取相同的数据时,读取到的数据可能会因为其他事务的提交而发生变化。

    示例:
    
    假设有两个事务 A 和 B。
    
    - 事务 A 读取了某个数据。
    - 事务 B 修改了那个数据并提交了。
    - 事务 A 再次读取相同的数据时,得到的结果与第一次读取时不同。
    
    总结
    事务A读取了一行的数据,事务B修改了这行数据 导致重复读取的数据不一样 即为不可重复读
    
  3. 幻读(Phantom Read)

    定义: 幻读是指在一个事务中执行查询时,另一事务对数据库的插入或删除操作导致前一个事务在再次执行相同查询时得到不同的结果。

    示例:
    
    假设有两个事务 A 和 B。
    
    事务 A 执行了某个查询,获取了一些数据。
    事务 B 插入了新的数据行。
    事务 A 再次执行相同的查询时,得到的结果集包含了事务 B 插入的新数据行(这些数据在第一次查询时不存在)。
    
    总结:
    事务A读取了表中所有数据的条数 ,事务B添加了一条数据 倒是事务A第二次读取表中所有数据的总条数不一样 即为幻读
    

事务的ACID

  1. 原子性(Atomicity):事务是一个不可分割的工作单位,要么全部执行成功,要么全部失败回滚。如果一个事务中的任何一个操作失败,整个事务都会被回滚到之前的状态,保持数据库的一致性。
  2. 一致性(Consistency):事务的执行使数据库从一个一致性状态转变为另一个一致性状态。事务的执行不能破坏数据库的完整性约束(例如,唯一性约束、外键约束等),数据库始终保持一致性。
  3. 隔离性(Isolation):多个事务同时执行时,每个事务都应该被隔离开来,不受其他事务的影响。隔离性确保事务之间的并发执行不会导致数据的不一致性。隔离级别用于控制事务之间的相互影响程度。
  4. 持久性(Durability):一旦事务成功提交,其结果应该永久保存在数据库中,即使系统崩溃或断电也不会丢失。数据库系统使用日志和其他机制来确保已提交的事务在系统失败后仍然可以恢复。
读未提交

​ 会产生脏读,不可重复读,幻读

  • 允许事务读取未被提交的数据变更。在这个级别下,一个事务可以读取到另一个事务尚未提交的数据,可能导致脏读(Dirty Read)问题。
  • 这是最低的隔离级别,因为它允许事务在其他事务未完成时查看它们的未提交更改。
读已提交

​ 会产生不可重复读和幻读

  • 保证一个事务只能读取到已经提交的数据变更。在这个级别下,其他事务的修改对当前事务是不可见的,直到其他事务提交。
  • 但是,可能会导致不可重复读(Non-Repeatable Read)问题,即在同一个事务内,两次读取相同记录的结果不一致。
可重复读

​ 会产生幻读

  • 保证一个事务在执行期间多次读取同一行数据时,所读取到的数据保持一致。其他事务的插入、更新操作对当前事务是不可见的。
  • 但是,可能会导致幻读(Phantom Read)问题,即在同一个事务内,两次查询条件相同但结果集不同的情况。
串行化

​ 多个并行事务串行执行,不会产生安全性问题

  • 最高的隔离级别,确保事务之间的完全隔离,每个事务都像是在系统中独立运行的。通过对事务进行串行化执行,避免了并发问题。

  • 这种级别通常通过对数据加锁来实现,以防止其他事务对数据的并发访问。虽然确保了最高级别的隔离和一致性,但可能会带来性能上的损失。

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值