【面试高高手】—— MySQL(14题)

1.MySQL索引失效的原因

1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
2.对于聚合索引,如果使用的索引不是第一个,则不会走索引。
3.like查询以%开头
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5.使用函数或表达式: 如果在查询中使用了函数或表达式来操作字段,那么索引可能会失效。例如,在WHERE子句中使用LOWER(column)函数会导致索引失效。
6.列类型不匹配: 当索引列和查询条件中的数据类型不匹配时,索引可能会失效。例如,将字符串类型的列与数字进行比较。

2.MySQL中的锁有哪些?

以InnoDB存储引擎作为基础。

  • 共享锁(Shared Lock,也称为读锁):
    意义:允许多个事务同时获取共享锁,用于防止其他事务获得排他锁,以确保数据读取的一致性。
    示例:一个事务获取了一行数据的共享锁,其他事务也可以获取相同行的共享锁,但不能获取排他锁。
    使用:
SELECT * FROM your_table WHERE some_column = 'some_value' FOR SHARE;

  • 排他锁(Exclusive Lock,也称为写锁):
    意义:排他锁是一种独占锁,只允许一个事务获得,用于确保在一个事务修改数据时,其他事务不能同时读取或修改相同的数据。
    示例:一个事务获取了一行数据的排他锁,其他事务无法同时获取相同行的排他锁或共享锁。
    使用:
SELECT * FROM your_table WHERE some_column = 'some_value' FOR UPDATE;

  • 意向共享锁(Intention Shared Lock):
    意义:用于表示一个事务打算在某个数据资源上获取共享锁,但事务还没有实际获取共享锁。意向共享锁通常是表级别的。
    示例:当一个事务打算在某个表上获取共享锁时,会在表级别设置意向共享锁,其他事务可以继续在表上设置共享锁。
    使用:
    意向锁通常不需要手动设置,MySQL会自动管理它们。当事务要获得某行的共享锁或排他锁时,会在表级别设置相应的意向锁。

  • 意向排他锁(Intention Exclusive Lock):
    意义:用于表示一个事务打算在某个数据资源上获取排他锁,但事务还没有实际获取排他锁。意向排他锁通常是表级别的。
    示例:当一个事务打算在某个表上获取排他锁时,会在表级别设置意向排他锁,其他事务可以继续在表上设置共享锁或意向共享锁。

  • 表锁(Table Lock):
    意义:锁定整个表,用于控制对整个表的访问。表锁一般不建议在高并发环境下使用,因为它会阻塞其他事务对表的访问。
    示例:一个事务获得了对整个表的排他锁,其他事务无法同时访问相同表。
    使用:表锁通常在表级别自动管理,但也可以通过手动方式获取。以使用LOCK TABLES语句来获取表级别的锁。

LOCK TABLES your_table WRITE; -- 获取表的排他锁
-- 执行对表的操作
UNLOCK TABLES; -- 释放锁
  • 行级锁(Row-level Lock):
    意义:锁定表中的单个行记录,允许多个事务同时操作不同的行记录,提高并发性。
    示例:一个事务获得了某行的排他锁,其他事务可以获得相同表中其他行的排他锁或共享锁。
    使用:行级锁是在事务中自动管理的,通常不需要手动设置。当你执行对某行的更新或删除操作时,MySQL会自动为该行设置排他锁,以确保其他事务不能同时修改。
START TRANSACTION;
UPDATE your_table SET some_column = 'new_value' WHERE id = 1; -- 设置行级排他锁
COMMIT; -- 释放锁

3.MySQL有哪些引擎?他们具有的特点?

1.innoDB

2.Myisam

3.Memory

区别:

innoDB跟myisam的默认索引是B+tree,Memory的索引默认为hash

InnoDB支持事务,支持外键,支持行锁,写入数据时操作快,MYSQL5.6版本以上才支持全文检索

myisam不支持事务,不支持外键,支持表锁,支持全文检索,读取速度快

memory所有的数据都保留在内存中,不需要进行磁盘的IO所以读取的速度很快,但是一旦关机的话表的结构会保留,但是数据会丢失,表支持Hash索引,因此查询效率很快。

4.你知道的索引的类型有哪些?

(1)普通索引:

  • B树索引: B树(或B+树)索引是MySQL中最常用的索引类型。它适用于等值查找、范围查询和排序操作。B树索引在内部是一颗平衡树,可以高效地支持数据的插入和删除操作。
  • 哈希索引: 哈希索引适用于等值查找操作,但不支持范围查询和排序。它使用哈希函数将索引列的值映射到索引桶中,因此查询时非常快速。

(2)唯一索引:唯一索引确保索引列中的值都是唯一的,不允许重复值。唯一索引可用于实施唯一性约束。
(3)主键索引:主键索引是一种特殊的唯一索引,它用于唯一标识表中的每一行。每个表只能有一个主键索引,主键索引通常与主键列一起创建。
(4)复合索引:复合索引是指将多个列组合在一起创建的索引。它适用于涉及多个列的查询,可以提高多列条件查询的性能。
(5)全文索引:全文索引用于全文搜索操作,通常用于文本字段(如文章内容或评论)。它允许你执行复杂的文本搜索,包括全文匹配和词语关联性分析。
(6)空间索引:空间索引适用于地理信息系统(GIS)应用,用于存储和查询地理空间数据(如地理坐标)。MySQL提供了特殊的空间数据类型和函数来支持空间索引。

5.如何设计海量的数据存储系统?

海量数据的解决方案:
页面上:使用缓存;页面静态化技术;
数据库层面: 分离数据库中活跃的数据; 批量读取和延迟修改;
读写分离; 使用NoSQL和Hadoop等技术;
分布式部署数据库; 应用服务和数据服务分离;
其他方面: 使用搜索引擎搜索数据库中的数据; 进行业务的拆分;
高并发情况下的解决方案: 应用程序和静态资源文件进行分离,静态资源可以使用CDN; 集群与分布式; 使用Nginx反向代理;

6.联合索引和单列索引的区别?

  • 组成方式:
    • 单列索引: 单列索引仅包含单个表列。每个索引项只包含一个列的值。
    • 联合索引: 联合索引由多个表列组成,这些列按照一定的顺序形成索引。每个索引项包含多个列的值的组合。

7. 你是如何优化SQL的?

  • 分析执行计划:在执行SQL查询之前,通过数据库管理工具或EXPLAIN语句来获取查询的执行计划。执行计划可以告诉你查询将如何执行,帮助你识别潜在的性能瓶颈。

  • 索引优化:
    确保表中的字段经常用于过滤或排序的字段都有合适的索引。不过要注意,过多的索引也会导致性能下降。
    使用复合索引来覆盖多个查询条件。
    定期重新构建或重新组织索引,以保持索引的效率。

  • 避免全表扫描:
    避免在大表上执行全表扫描,尽量使用索引或其他优化技巧来加速查询。
    使用适当的条件来限制结果集的大小,以减少全表扫描的需求。

  • 优化查询语句:
    避免使用SELECT *,而是只选择需要的列。
    使用合适的WHERE子句来限制结果集的大小。
    避免嵌套子查询,如果可能的话,尽量使用连接操作。
    使用EXISTS或IN子句来代替NOT IN,因为后者通常性能较差。

  • 合理使用缓存:使用数据库查询缓存(如MySQL的Query Cache)来缓存查询结果,减少重复查询数据库的次数。

  • 定期维护数据库:定期清理不再使用的数据,进行数据库备份和恢复,以保持数据库的健康状态。

  • 分区表:对大表进行分区,以减轻查询的压力,特别是在历史数据和活跃数据的管理上。

  • 硬件升级:如果可能的话,升级数据库服务器的硬件,包括CPU、内存、磁盘等,以提高数据库性能。

  • 使用数据库优化工具:许多数据库管理系统提供了优化工具,如MySQL的mysqltuner,可以帮助你分析数据库性能并提出优化建议。

  • 监控和调整:定期监控数据库性能,查看慢查询日志,并根据需要调整查询和索引以解决性能问题。

  • 考虑缓存层:在适当的情况下,引入缓存层(如Redis或Memcached)来减轻数据库的负担,特别是对于读密集型应用。

8. 除了常规的SQL优化,你在实际场景中还是用到了什么优化手段?

  • 缓存策略:
    使用缓存来存储频繁访问的数据,以减少数据库查询次数。常见的缓存技术包括内存缓存(如Redis、Memcached)和分布式缓存(如Ehcache、Hazelcast)。使用合适的缓存失效策略,以确保缓存中的数据与数据库中的数据保持一致。
  • 数据分片:
    对于大型应用,可以考虑将数据分散到多个数据库实例或分片中,以分摊负载并提高并发性能。
  • 异步处理:将耗时的操作(如发送电子邮件、生成报表等)放入消息队列中,异步处理,以减轻主要应用的负担,提高响应速度。
  • 负载均衡:使用负载均衡器来分发流量到多个应用服务器,以确保请求得到平均分配,提高系统的可用性和性能。
  • 数据库分库分表:
    对于大型数据库,可以将数据分散到多个数据库实例或表中,以减轻单一数据库的负担,提高查询性能。
  • 延迟加载:对于复杂对象关系,延迟加载可以延迟加载相关数据,只在需要时才进行加载,减少了不必要的数据查询。
  • CDN(内容分发网络):使用CDN来分发静态资源(如图片、样式表、脚本),降低服务器负载,提高资源加载速度。
  • 数据库连接池:使用数据库连接池来管理数据库连接,避免频繁地创建和销毁连接,以提高数据库访问性能。
  • 懒加载:对于前端界面,可以使用懒加载技术,延迟加载页面上不可见区域的内容,提高页面加载速度。
  • 水平扩展:在需要时,考虑水平扩展应用服务器,添加更多的服务器以处理更多的请求。
  • 合并和压缩资源:合并多个CSS和JavaScript文件,并对它们进行压缩,以减少页面加载时间。
  • 性能监控和分析工具:
    使用性能监控工具(如New Relic、AppDynamics、Prometheus等)来监视应用性能,识别性能瓶颈,并采取相应的措施进行优化。

9. 死锁你知道怎么用吗?好处是什么?

10. MySQL日志类型有哪些?

重做日志(redo log)
回滚日志
二进制日志
错误日志
慢查询日志
一般查询日志
中继日志

11.MySQL支持事务吗?说说你对事务的理解?

支持!事务就是指一组操作的集合,要么全部成功,要么全部失败这就是事务。事务是在引擎层进行实现的,也就是说并不是所有的引擎都可以支持事务,MyISAM引擎就不支持事务,InnoDB支持事务的。InnoDB是MySql默认的引擎。

12. 说下事务的四大特性是什么?

  • 原子性
    事务最基本的操作单元,要么全部成功,要么全部失败,不会结束在某个中间环节,事务在执行过程中发生错误,会回滚到事务开始的状态,就像这个这个事务从来没有执行过一样。
  • 一致性
    指的是在一个事务执行之前和执行之后, 数据库必须处在一致性状态,如果事务成功的执行,那么系统中所有变化将正确的应用,系统处于有效状态。
  • 隔离性
    指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间,由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是修改之后的状态,事务不会查看到中间状态的数据。
  • 持久性
    指的是只要事务成功结束,它对数据库所做的更新就必须永久的保存下来,数据成功落盘。即使发生系统崩溃,重新启动数据库后,数据库还能恢复到事务成功结束的状态。

13. 你知道事务的隔离级别吗?

MySql的事务隔离级别一共分为4种,用来限定事务内外的哪些改变是可见的,哪些是不可见的。事务隔离级别越低,支持并发的性能越高,系统的开销越小!

  • 读未提交(Read Uncommitted):
    一个事务还未提交(commit)变更就被其它事务读取到了。这个隔离级别是很少在实际应用中看到的,因为他造成的事情很多,比如脏读,脏读就是一个事务读取到了其它事务还未提交的内容。而且这种隔离级别的性能也不比另外三种好多少,所以它是最少被实际应用的。
  • 读已提交(Read committed):
    一个事务只能看到其它事务已经提交(commited)的内容。因为它满足隔离的简单定义,所以这是大多数数据库所采用的的隔离级别,但是并不是MySql所默认的。这种隔离级别会造成不可重复读,不可重复读就是同一条SQL不能重复执行,因为两次查询出来的内容可能不一致。原因同一事务的其他实例在该实例处理其间可能会有新的commit(修改了内容),导致查询的内容不一致。
  • 可重复读(Repeatable Read):
    同一条SQL查询多次,会看到同样的数据行。这是MySql默认的隔离级别。但是这种隔离级别也会出现一些问题,比如幻读,幻读就是当用户读取某一范围内的数据时,另一个事务又在该范围内插入了新的数据,当用户再次读取该范围内的数据时就会出现“幻影”行(行数不一致)。幻读和不可重复读有些类似,都是表现出两次读取的内容不一致的状况,但是二者还是有差别的,幻读侧重的是删除和新增,不可重复读侧重的是修改,解决幻读的方法是锁住满足条件的行,而解决不可重复读的方法是锁住表。幻读在InnoDB和FaIcon存储引擎通过多版本控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
    对于快照读,InnoDB 使用 MVCC 解决幻读,对于当前读,InnoDB 通过 gap locks 或 next-key locks 解决幻读。
  • 串行化(Serializable):
  • 强制事务排序,使多个事务之间不发生冲突,排着队一个个的执行。此隔离级别可以解决幻读的问题,实现的原理是在每个读的数据行上加锁,由于事务的串行化会导致大量的超时和锁竞争,效率很低。

14.事务并发会出现哪些问题?

  • 脏读:
    一个事务读取到另一个未提交的数据。原因是在一个事务读取数据的前后另一个事务对该数据做了修改。
  • 不可重复读:
    在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。重点是读取的数据内容不一致。
  • 幻读:
    在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。重点是读取的数据的条数不一致。

猜你喜欢

转载自blog.csdn.net/qq_42785250/article/details/133012700