数据库(五)

2020-06-25  本文已影响0人  焰火青春

1. MySQL 基础考点

2. 什么是事务?

MySQL 事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

可以看做是一系列 SQL 语句的集合,事务要么全部执行成功,要么执行失败(回滚),比较常见的有银行转账。

2.1 事务的 ACID 特性

2.2 事务控制语句

语句 说明 语句
begin/start transaction 开启事务 commit/commit work 提交事务(永久)
savepoint identifier savepoint 允许在事务中创建一个保存点(可有多个) release savepoint identifier 删除保存点(需指定保存点)
rollback to identifier 回滚到标记点 set transaction 设置事务隔离级别(innodb 隔离级别有:uncommitted/read committed/repeatable read 、 serializable

savepoint 保留点

savepoint 是在数据库事务处理中实现“子事务”(subtransaction),也称为嵌套事务的方法。事务可以回滚到 savepoint 而不影响 savepoint 创建前的变化, 不需要放弃整个事务。

ROLLBACK 回滚的用法可以设置保留点 SAVEPOINT,执行多条操作时,回滚到想要的那条语句之前。

mysql> select * from test;                                                                                     
+----+------+                                                                                                  
| id | name |                                                                                                  
+----+------+                                                                                                  
|  1 | rose |                                                                                                  
|  2 | lila |                                                                                                  
+----+------+                                                                                                  
2 rows in set (0.00 sec)                                                                                       
# 开启事务                                                                                             
mysql> begin;                                                                                                  
Query OK, 0 rows affected (0.00 sec)       

# 设置保留点
mysql> savepoint insert_before;                                                                                
Query OK, 0 rows affected (0.00 sec)                                                                                                                                                 
mysql> insert into test(name) values('john');       # 插入一条数据                                     
Query OK, 1 row affected (0.00 sec)                                                                            
mysql> select * from test;                                                                                     
+----+------+                                                                                                  
| id | name |                                                                                                  
+----+------+                                                                                                  
|  1 | rose |                                                                                                  
|  2 | lila |                                                                                                  
|  4 | john |                                                                                                  
+----+------+                                                                                                  
3 rows in set (0.00 sec)                                                                                       
                                                                                                       # 回滚到保留点
mysql> rollback to insert_before;                                                                              
Query OK, 0 rows affected (1.00 sec)                                                                           
# 数据没有被修改                                                                                        mysql> select * from test;                                                                                     
+----+------+                                                                                                  
| id | name |                                                                                                  
+----+------+                                                                                                  
|  1 | rose |                                                                                                  
|  2 | lila |                                                                                                  
+----+------+                                                                                                  
2 rows in set (0.00 sec)                                                                               

Tips:MySQL 命令行默认事务是自动提交的,即无需手动 commit,若要禁止自动提交,可设置 set autocommit=0

2.3 MYSQL 事务处理方法

1、用 BEGIN, ROLLBACK, COMMIT来实现

2、直接用 SET 来改变 MySQL 的自动提交模式:

mysql> create table test(
    -> id int primary key auto_increment,
    -> name varchar(32))
    -> engine=innodb;
Query OK, 0 rows affected (1.62 sec)

mysql> select * from test;
Empty set (0.00 sec)

mysql> begin;       # 开启事务
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test(name) values('rose');
Query OK, 1 row affected (0.00 sec)

mysql> insert into test(name) values('lila');
Query OK, 1 row affected (0.00 sec)

# 提交
mysql> commit;
Query OK, 0 rows affected (0.07 sec)

mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | rose |
|  2 | lila |
+----+------+
2 rows in set (0.00 sec)

事务回滚:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test(name) values('john');
Query OK, 1 row affected (0.00 sec)

mysql> rollback;
Query OK, 0 rows affected (0.13 sec)

mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | rose |
|  2 | lila |
+----+------+
2 rows in set (0.00 sec)

参考:https://www.runoob.com/mysql/mysql-transaction.html

3. 事务并发控制

如果不对事务进行并发控制,可能产生四种异常情况:

4. 事务隔离级别

为了解决事务并发控制异常,定义了 4 种事务隔离级别:

隔离级别越低通常可以执行更高的并发,系统开销有越低

幻读:当某个事物在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围内的记录时,会产生幻行(Phantom Row),InnoDB 和 XtraDB 引擎通过多版本并发控制(MVCC)解决了幻读问题

5. 解决高并发场景下的插入重复

高并发场景下,写入数据库会有数据重复问题,以下是几个避免重复插入的思路:

6. 乐观锁和悲观锁

乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。

先修改,更新时候发现数据已变了就回滚(check and set)

悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

先获取锁再执行操作,一锁二查三更新(select for update)

使需要根据响应速度、冲突频率、重试代价来判断使用哪一种

乐观锁常见的两种实现方式

乐观锁一般会使用版本号机制或CAS算法实现。

一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

举一个简单的例子:
假设数据库中帐户信息表中有一个 version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。

  1. 操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 50(100-$50 )。
  2. 在操作员 A 操作的过程中,操作员B 也读入此用户信息( version=1 ),并从其帐户余额中扣除 20 (100-$20 )。
  3. 操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。
  4. 操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “ 提交版本必须大于记录当前版本才能执行更新 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。

这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作员A 的操作结果的可能。

参考文章:

7. MySQL 常用数据类型

image image

[图片上传失败...(image-7342b-1593095890096)]

8. InnoDB 和 MyISAM 引擎区别

9. MySQL查找数据结构

9.1 MySQL 查找结构进化史

[图片上传失败...(image-2b1fc0-1593095890096)]

9.2 B-Tree

MySQL 查找结构使用的是多路平衡查找树,也就是 B-Tree,那么为什么要用 B-Tree,它有什么优点:

image

B+Tree

B+Tree 是 B-Tree 的变形:

[图片上传失败...(image-ce16f8-1593095890096)]

10. MySQL 索引

什么是索引

索引类型

什么时候创建索引

建表的时候需要根据查询需求来创建索引:

创建索引需要注意的

什么时候索引会失效

记忆口诀:模糊匹配、类型隐转、最左匹配

聚集索引和非聚集索引

image image image

非聚集和聚集索引的文件存储方方式

# 非聚集
create table myisam_table(
'id' integer primary key,
 title varchar(80)
) engine = MYISAM;

# 聚集
create table innodb_table(
'id' integer primary key,
'url_md5' char(32),
key 'index_url' ('url_md5')
) engine = InnoDB;

如何消除慢查询

所谓馒查询即查询时间较慢的 SQL 语句,在高并发时影响很大,因此我们要尝试去消除慢查询:

11. MySQL 连接

MySQL 表之间连接大致分为以下几类:

示例数据表:

# A 表               # B 表
id  val             id  val 
1   ab              1   ab
2   a               3   b

内连接

将左表和游标能够关联的数据连接后返回,类似于 "交集"。

语法:

select * from A inner join B on a.id = b.id

mysql> select * from A inner join B on a.id=b.id;
+----+------+----+------+
| id | val  | id | val  |
+----+------+----+------+
|  1 | ab   |  1 | ab   |
+----+------+----+------+

外连接

语法:

select * from A left join B on a.id = b.id
select * from A right join B on a.id = b.id
mysql> select * from A left join B on a.id=b.id;
+----+------+------+------+
| id | val  | id   | val  |
+----+------+------+------+
|  1 | ab   |    1 | ab   |
|  2 | a    | NULL | NULL |
+----+------+------+------+
2 rows in set (0.00 sec)

mysql> select * from A right join B on a.id=b.id;
+------+------+----+------+
| id   | val  | id | val  |
+------+------+----+------+
|    1 | ab   |  1 | ab   |
| NULL | NULL |  3 | b    |
+------+------+----+------+
2 rows in set (0.00 sec)

思考题

12. Redis 数据库

12.1 Redis 常考题

什么是缓存,为什么要用缓存

缓存有数据库缓存、文件缓存以及内存缓存,内存缓存速度最快,也是最常用的。常见的内存缓存有:Redis 和 Memcached。

计算机各种操作时间对比:

操作 响应时间 操作 响应时间
打开一个网站 几秒 在数据库查询一条记录(有索引) 十几毫秒
机械磁盘一次寻址定位 4 毫秒 从机械磁盘顺序读取1MB数据 2毫秒
从SSD磁盘顺序读取1MB数据 0.3毫秒 从远程分布缓存Redis读取一个数据 0.5毫秒
从内存中读取1MB数据 十几微秒 Java程序本地方法调用 几微秒
网络传输2KB数据 1微秒

Redis 和 Memcached 主要区别

image

Redis 常用数据类型和使用场景

12.2 Redis 内置实现

对应中高级工程师,需要了解 Redis 各种类型的 C 底层实现方式

深入学习参考书籍:《Redis 设计与实现》

跳跃表结构

image

12.3 Redis 持久化

Redis 支持两种方法实现持久化:

12.4 Redis 事务

Redis 事务和 MySQL 有什么不同:

12.5 Redis 分布式锁

如何实现分布式锁:

12.6 缓存模式

常用的缓存使用模式:

先更新缓存再更新数据库,并发写入操作可能导致缓存读取的是 脏数据

12.7 如何解决缓存穿透问题

(必然不存在的数据)大量查询不到的数据的请求落到后端数据库,数据库压力增大就会导致缓存穿透,有可能被黑客攻击。

https://blog.csdn.net/hjm4702192/article/details/80518952

12.8 如何解决缓存击穿问题

是指某个热点的 key 在过期瞬间有大量请求访问这个 key,缓存里没有就去数据库中查找,从而增加数据库压力,导致缓存被击穿。

12.9 如何解决缓存雪崩问题

缓存不可用或者大量缓存 key 同时失效,大量请求直接打到数据库

Redis 应用

Redis 的另一种应用就是实现分布式锁

分布式锁:https://blog.csdn.net/t8116189520/article/details/91383256

13. 死锁

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就有可能产生死锁。多个事务同时锁定同一个资源时也会产生死锁。

# 事务一
start transaction;
update stockprice set close = 45.5 where stock_id = 4 and date = '2002-05-01';
update stockprice set close = 19.8 where stock_id = 3 and date = '2002-05-02';
commit;

# 事务二
start transaction;
update stockprice set high = 20.12 where stock_id = 3 and date = '2002-05-02';
update stockprice set close = 47.20 where stock_id = 4 and date = '2002-05-01';
commit;

若以上两个事务都执行了第一条 update 语句,更新了一行数据,同时也锁定了该行数据,接着去尝试执行第二条 update 语句时,发现该行已被对方锁定,然后两个事务都等待对方释放锁,同时又持有对方需要的锁,则陷入死循环。除非有外力才有可能解除死锁

解决方法

死锁发生后,只有部分或完全回滚其中一个事务,才能打破死锁,大多数情况下只需重新执行因死锁回滚的事务即可。

InnoDB 目前除了死锁的方法:将持有最少行级排他锁的事务进行回滚(这是相对比较简单的死锁回滚算法)。

参考文章:https://www.cnblogs.com/hhthtt/p/10707541.html

14. 并发控制

多个查询在同一时刻修改数据,都会产生并发控制。

如果两个进程同时对某张数据表进行操作,A 进程要读取数据表中的记录,而 B 进程要修改记录,那么两种就有可能会发生冲突。就有可能导致数据损坏,为了避免这种情况发生,就要通过设置锁(lock)来防止数据损坏。

如果 A 进程在读取数据,B 进程想修改数据,而数据表已被 A 进程锁定了。就必须等待,释放锁后才能继续修改。

14.1 读写锁/共享(排他)

多个用户在同一时刻并发读取数据一般不会有问题,但如果某个客户在读取,同时另一个用户试图删除。读的用户就有可能报错退出,也有可能读取到不一致的数据,为了安全起见,即使读取数据也需要注意。

解决这类问题就是使用并发控制,即在处理并发读或写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。这两种类型的锁通常被称为 共享锁(shared lock)和 排他锁(exclusive lock),页脚读锁(read lock)和写锁(write lock)

读锁

共享的,相互不阻塞,多个客户在同一时刻可以同时读取同一个资源,互不干扰。

写锁

排他的,一个写锁会阻塞其他的写锁和读锁,这样出于安全策略的考虑。

14.2 锁粒度

加锁也会耗费资源,锁的各种操作,如:获得锁、检查锁是否被解除、释放锁等,都会增加系统的开销。一旦有很多锁的时候,必然要占用大量的系统资源。因此就需要一种理想的 锁策略,只对会修改的数据片进行精确锁定。在给定的资源上,锁定的数据量越小,则系统的并发程度越高,只要相互之间不发生冲突即可。

锁策略

在锁的开销和数据的安全性之间寻求平衡,这种平衡也会影响到性能。大多数商业数据库没有更多的选择,而是在表上添加 行级锁(row level lock),并以各种复杂的方式来实现,以便在锁比较多的情况下尽可能地提供更好的性能。

而 MySQL 有多种选择,基本上每种引擎都可以实现自己的锁策略和锁粒度,将锁粒度固定在某个基本,可以为某些特定的应用场景提供更好的性能,但是也会失去对另外一些应用场景的良好支持。

两种常用的锁策略:表锁、行级锁

表锁(table lock)

MySQL 最基本的锁策略,开销最小,它会锁定整张表。一个用户要对表进行写操作(插入、删除、更新等),就先要获得写锁(会阻塞读操作)。只有当没有写锁时,其他用户才能获取读锁,读锁之间相互不阻塞。

写锁等级高于读锁,因此写锁请求可能会被插入到读锁队列前面。

行级锁(row lock)

可以最大程度支持并发处理(也会带来最大的锁开销)。

行级锁只在存储引擎层实现,而 MySQL 服务器层没有实现,所有的存储引擎都以自己的方式实现了锁机制。

MySQL 逻辑架构图

image

15. 为什么使用 B+ 树作为索引结构

一般来说,索引本身也很大,不可能全部存储在内存中,往往是以索引文件的形式存储的磁盘上。但是这样的话,索引查找就必然要产生磁盘 I/O 消耗,相对于内存读取速度,磁盘 I/O 读取速度要慢很多。因此衡量一个索引优劣的指标就是要尽量减少查找过程中磁盘 I/O 的存取次数。

B+Tree 结构可以在读取相同磁盘块同时,尽可能多的加载索引结构,来提高索引命中效率,从而达到减少磁盘 I/O 的读取次数。

B-Tree 结构

image

利用了磁盘块特性进行构建的数,每个磁盘块一个节点,每个节点包含了很多关键字。把树的节点关键字增多后树的层级比原来的二叉树少了,减少了数据查找的次数和复杂度。

利用了磁盘预读原理,将每一个节点的大小设为等于一个页(每页 4K),这样每个节点只需一次 I/O 就可以完全载入。

B+Tree 结构

[图片上传失败...(image-122421-1593095890096)]

B-Tree 的变种,数据只存储在叶子节点。这样在 B-Tree 基础上每个节点存储的关键字树更多,树的层级更少,所有查询更快。所有关键字指针都存在叶子节点,所以每次查找的次数相同,查询速度也更稳定。

B-Tree 检索一次最多需要访问 h(树的深度)个节点,检索一次最多需要 h-1 次 I/O 操作(根节点常驻内存),渐进复杂度为 O(h)。一般在实际应用中,出度 d(节点最大的分支数)是非常大的数字,通常超过 100,因此 h 非常小(通常不超过 3)。

B+Tree 更适合所有,原因在于内节点出度 d 有关,d 越大索引的性能越好,而出度的上限取决于节点内 key 和 data 的大小。

B-Tree 和 B+Tree 对比

树的深度越大检索效率越低

参考文章:

16. MySQL 数据库的优化?

1、SQL 语句优化

2、索引优化

3、数据库表结构优化

4、系统配置优化

5、服务器硬件优化

6、事务、锁定表

7、通过 explain 查询和分析 SQL 的执行计划

image

explain 返回的每列的含义

1、Using filesort

使用文件排序的方式排序,当返回值是这个时,查询就需要优化了。表示 MySQL 需要进行额外的步骤来发现如何对返回的行排序,它根据连接类型以及存储排序键值和匹配条件的全部的行指针来排序全部行。

2、Using temporary

使用 临时表方式,当返回值为这个时,查询就需要优化了。MySQL 需要创建一个临时表来存储结果,通常发在对不同的列集进行 order by 上,而不是 group by 上。

17. 如何定位查询瓶颈以及优化查询

MySQL提供了慢查询可以快速定位性能瓶颈

# 查看慢查询日志是否开启,off 为关闭
show variables like 'slow_query_log';

# 查看 log_queries_not_using_indexes 是否开启
show variables like '%log%';

# 开启 log_queries_not_using_indexes
set global log_queries_not_using_indexes=on;

# 开启慢查询日志
set global slow_query_log=on;

# 查看慢查日志记录时间,0 表示时刻都会记录,生产环境中不能为 0
show variables like 'long_query_time';

# 设置查询记录的时间(即查询超过 0s 的SQL语句都会被记录在慢查日志中)
set global long_query_time=0;

# 查看慢查询日志存储位置
show variables like 'slow_query_log_file';

# 指定慢查询日志存储位置
set global show_query_log_file='/var/lib/mysql/homestead-slow.log';

# 记录没有使用索引的sql
set global log_queries_not_using_indexes=on;

慢查日志分析工具

18. 面试题

1、MySQL锁有几种;死锁是怎么产生的,为何,以及如何分区、分表

数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。

常见的MYSQL锁有三种级别:页级、表级、行级

所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB。

https://blog.csdn.net/q1925387431/article/details/86612581

https://blog.csdn.net/weixin_42358062/article/details/80731501

2、MySQL的char varchar text的区别

3、了解join么,有几种,有何区别,A LEFT JOIN B,查询的结果中,B没有的那部分是如何显示的(NULL)

三种,

B 没有的部分以 NUll 形式显示。

4、索引类型有几种,BTree索引和hash索引的区别

索引可以大大提高MySQL的检索速度

5、手写:如何对查询命令进行优化

# 尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
# 尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
select id from t where num is null
# 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

# 尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

# 尽量避免在 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

# 字段按需提取,尽量少用 select *,而是要按照提取字段提取
select a, b from t

# 尽量使用exists代替select count(*) 来判断是否存在记录。优化器优化exists谓词时支持短路功能。只要找到一行,不需要再扫描其他行就可以确定该表是否包涵行了。count函数只有在统计表中所有行的行数时使用。

# 尽量使用(not) exists代替(not) in 操作,in的sql性能总是比较低的。

# 尽量使用“>=“,不用使用”>“

# 在where 子句中,任何对列的操作(函数、计算等)讲导致索引失效,这些操作应该尽可能地移至等号右边,如where substring(id,1,1)=‘a‘,应该写成where id like 'a%‘;where result*10> 30应该写成where result >30;

# 尽量使用not in,可以用left outer join代替它。

https://www.cnblogs.com/Mryang-blog-cn/p/SQLYOUHUA.html

6、NoSQL了解么,和关系数据库的区别;redis有几种常用存储类型

NoSQL(not only SQL),非关系型数据库,数据表之间没有相应关系,以键值对形式存储(存储方式不同)。对事物支持不怎么好,查询方式不同。

redis 常用存储类型:list、set、有序集合、str、hash

https://www.cnblogs.com/sunzhiqi/p/10869655.html

7、redis、memcached

1、Redis

NoSQL (Not Only SQL)数据库即非关系型数据库,与关系型数据库区别:

常见的 NoSQL有:Redis、MongoDB、Hbase hadoop 以及 Cassandra hadoop 等

优势

常用数据类型:str、hash、set、有序集合、列表

应用场景:做缓存


2、memcached

Memcached 是一个自由开源的,高性能,分布式内存对象缓存系统。Django 原生支持的最快最有效的缓存系统。对于大多数场景,我们推荐使用Memcached,数据缓存在服务器端。

8、为什么要使用缓存

在 Django 项目中,当用户请求达到视图后,视图会先从数据库中提取数据,然后将其放在模板中渲染。若每次都从数据库中提取数据,必然会导致网站性能降低。不仅服务器压力大,而且客户端也无法及时获得响应。

如果能将渲染后的结果放在速度更快的介质中,每次请求来时,先从这个介质中检查是否有对应的资源。若有直接取出响应即可,大大提高了网站的性能,节省了数据和渲染的时间,而且能提高用户体验。

9、缓存应用场景

缓存主要适用于对页面实时性要求不高的页面。存放在缓存的数据,通常是频繁访问的,而不会经常修改的数据。如:

像实时监控股票走势、实时显示网站访问量这种需要实时刷新的数据,就不适合用缓存,需要从数据库中立马提取数据。

10、MySQL 常见数据库引擎及比较?

注意:同一数据库可使用多种存储引擎,若对表要求比较高的事务处理,可选择 InnoDB;若对查询要求较高的表,可选择 MyISAM;若该数据库需要一个用于查询的临时表,可选择 MEMORY

11、什么是事务?MySQL 如何支持事务?

事务是由一步或几步数据库操作序列组成的逻辑执行单元,这系列操作要么全部执行,要么全部放弃执行。

程序与事务是两个不同的概念,一般程序中可能包含多个事务。

事务的 ACID 特性:

MySQL 事务处理两者方法:

12、主键和外键的区别?

13、MySQL 常见函数?

sum、abs、floor

14、列举创建索引但无法命中索引的几种情况

15、如何开启慢查询日志?

16、数据库优化方案?

17、简述 MySQL 执行计划?

MySQL 数据库中,在 select 查询语句前加上 EXPLANDESC 关键字,即可查看该查询语句的执行计划,分析执行计划是优化慢查询的重要手段。

18、简述数据库读写分离?

前提:主备两台服务器同步数据

利用数据库的主从分离:主(用于增加、删除、更新),从(用于查询)。

上一篇 下一篇

猜你喜欢

热点阅读