MySQL面试题及SQL优化

1. 数据库连接查询

  • 内联接(Inner Join):匹配2张表中相关联的记录。
  • 左外联接(Left Outer Join):除了匹配2张表中相关联的记录外,还会匹配左表中剩余的记录,右表中未匹配到的字段用NULL表示。
  • 右外联接(Right Outer Join):除了匹配2张表中相关联的记录外,还会匹配右表中剩余的记录,左表中未匹配到的字段用NULL表示。在判定左表和右表时,要根据表名出现在Outer Join的左右位置关系

2.数据库中的聚合函数

  • COUNT:统计行数量
  • SUM:获取单个列的合计值
  • AVG:计算某个列的平均值
  • MAX:计算列的最大值
  • MIN:计算列的最小值

3 数据库三范式

  1. 第一范式:1NF原子性,列或者字段不能再分,要求属性具有原子性,不可再分解
  2. 第二范式:2NF 唯一性,一张表只说一件事,是对记录的惟一性约束,要求记录有惟 一标识
  3. 第三范式:3NF 直接性,数据不能存在传递关系,即每个属性都跟主键有直接关系, 而不是间接关系。

4 MySQL的默认隔离级别

         MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ (可重读)。

5 数据库锁

5.1 行级锁和表级锁

  1. 主要是针对锁粒度划分的,一般分为:行锁、表锁、库锁
  • 行锁:访问数据库的时候,锁定整个行数据,防止并发错误。
  • 表锁:访问数据库的时候,锁定整个表数据,防止并发错误。
  1. 行锁 和 表锁 的区别
  • 表锁: 开销小,加锁快,不会出现死锁;锁定力度大,发生锁冲突概率高,并发度最低
  • 行锁: 开销大,加锁慢,会出现死锁;锁定粒度小,发生锁冲突的概率低,并发度高

5.2 悲观锁和乐观锁

  • 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会 block 直到这个锁被释放。
             传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
  • 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
             乐观锁适用于多读的应用类型 ,这样可以提高吞吐量,像数据库如果提供类似于 write_condition 机制的其实都是提供的乐观锁。

6. MySQL由哪些部分组成, 分别用来做什么

MySQL面试题及SQL优化_第1张图片

  1. 连接器: 管理连接, 权限验证.
  2. 分析器: 词法分析, 语法分析.
  3. 优化器: 执行计划生成, 索引的选择.
  4. 执行器: 操作存储引擎, 返回执行结果.
  5. 存储引擎: 存储数据, 提供读写接口.

7. 数据库存储引擎概述

数据库存储引擎
        是数据库底层软件组织,数据库管理系统(DBMS) 使用数据引擎进行创建、查询、更新和删除数据。
        不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。
存储引擎主要有

  1. MyIsam ,
  2. InnoDB,
  3. Memory,
  4. Archive,
  5. Federated 。

8. MyISAM 和 InnoDB 的区别

  • lnnoDB引擎:
            MySQL5.5版本的默认引擎,innoDB引擎提供了对数据库acid事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统
            MySQL运行的时候,innoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行select count(*) from table指令的 时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的, 所以在并发度较高的场景下使用会提升效率的。

  • MyIASM引擎:
            MySQL5.5版本的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。
            不过和InnoDB不同的是, MyIASM引擎是保存了表的行数,于是当进行select count(*) from table语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将MyIASM作为数据库引擎的首选。

总结
1. InnoDB支持事务, MyISAM不支持
2. InnoDB支持行级锁, MyISAM支持表级锁.
3. InnoDB支持外键, MyISAM不支持.
4. MyISAM支持全文索引, InnoDB不支持(但可以使用Sphinx插件)

9 索引的概念和优点

  • 概念:
            索引存储在内存中,为服务器存储引擎为了快速找到记录的一种数据结构。
  • 索引的主要作用:
            加快数据查找速度,提高数据库的性能。
  • 优点:
    (1) 创建唯一性索引,保证数据库表中每一行数据的唯一性
    (2) 大大加快数据的检索速度,这也是创建索引的最主要的原因
    (3) 加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意 义。
    (4) 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组 和排序的时间。

10 索引的分类

  • 普通索引:最基本的索引,它没有任何限制。
  • 唯一索引:与普通索引类似,不同的就是索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
  • 主键索引:它是一种特殊的唯一索引,用于唯一标识数据表中的某一条 记录,不允许有空值,一般用 primary key 来约束。
  • 联合索引(又叫复合索引):多个字段上建立的索引,能够加速复合查 询条件的检索。
  • 全文索引:老版本 MySQL 自带的全文索引只能用于数据库引擎为 MyISAM 的数据表,新版本 MySQL 5.6 的 InnoDB 支持全文索引。默认MySQL 不支持中文全文检索,可以通过扩展 MySQL,添加中文全文检索或为中文内容表提供 一个对应的英文索引表的方式来支持中 文。

11. 什么是最左前缀法则以及如何设计最左法则

        MySQL中的索引可以以一定顺序引用多列,这种索引叫作联合索引。如User 表的name和city加联合索引就是(name,city),而最左前缀原则指的是最左优先, 如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以被用到。即以最左边的为起点任何连续的索引都能匹配上

        例如:创建(a,b,c)复合索引,以a为最左,则只能使用ab,ac和abc三种组合

        在创建联合索引时,索引字段的顺序需要考虑字段值去重之后的个数,较多的放前面。

12. 索引的底层实现原理(高薪常问)

        索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
        具体来说MySQL中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是B+树实现的,B+树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所以索引的性能也是更好的。

13. B+树的特点和优势

  • B+树的特征
    1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点
    2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指 针,且叶子结点本身依关键字的大小自小而大顺序链接
    3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最 小)元素。
  • B+树的优势
    1.单一节点存储更多的元素,使得查询的IO次数更少。
    2.所有查询都要查找到叶子节点,查询性能稳定。
    3.所有叶子节点形成有序链表,便于范围查询。

14. 怎么验证MySQL的索引是否满足需求

        使用explain查看SQL是如何执行查询语句的,从而分析你的索引是否满足需求。
explain语法:
        explain select * from table where type=1。

15. 如何避免索引失效(高薪常问)

  1. 范围查询, 右边的列不能使用索引, 否则右边的索引也会失效
  2. 不要在索引上使用运算, 否则索引也会失效
  3. 字符串不加引号, 造成索引失效.
  4. 尽量使用覆盖索引, 避免 select *, 这样能提高查询效率.
  5. or 关键字连接, 用 or 分割开的条件,如果 or 前面的列有索引,or 后面的列没有索引,那么查询的时候前后索引都会失效; 如果一定要用 or 查 询,可以考虑下 or 连接的条件列都加索引, 这样就不会失效了

16. 优化(高薪常问)

16.1 MySQL问题排查都有哪些手段

  • 使用show processlist命令查看当前所有连接信息。
  • 使用explain命令查询SQL语句执行计划。
  • 开启慢查询日志,查看慢查询的SQL。

16.2 说说对 SQL 语句优化有哪些方法?

  1. Where 子句中:where 表之间的连接必须写在其他 Where 条件之前, 那些可以过滤掉最大数量记录的条件必须写在 Where 子句的末尾,HAVING 最后。
  2. 用 EXISTS 替代 IN、用 NOT EXISTS 替代 NOT IN。
  3. 避免在索引列上使用计算
  4. 避免在索引列上使用 IS NULL 和 IS NOT NULL
  5. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  6. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
  7. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

16.3 如何做MySQL的性能优化

  • 为搜索字段创建索引。
  • 避免使用select *,
  • 列出需要查询的字段。垂直分割分表。
  • 选择正确的存储引擎。

16.4 大表如何优化

        当MySQL单表记录数过大时,数据库的CRUD性能会明显下降;
一些常见的优化措施如下
        限定数据的范围: 务必禁止不带任何限制数据范围条件的查询语句。比如:我们当用户在查 询订单历史的时候,我们可以控制在一个月的范围内;
        读/写分离: 经典的数据库拆分方案,主库负责写,从库负责读;
        水平分表: 保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。 水平拆分可以支撑非常大的数据量。 水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。举个例子:我们可以将用户信息表拆分成多个用户信息表,这样就可以避免单一表数据量过大对性能造成影响。

16.5 分库分表之后,id 主键如何处理

        因为要是分成多个表之后,每个表都是从 1 开始累加,这样是不对的,我们需要一个全局唯一的 id 来支持。

生成全局 id 有下面这几种方式

  • UUID:不适合作为主键,因为太长了,并且无序不可读,查询效率低。比较适合用于生成唯一的名字的标示比如文件的名字。
  • 数据库自增 id: 两台数据库分别设置不同步长,生成不重复ID的策略来实现高可用。这种方式生成的 id 有序,但是需要独立部署数据库实例,成本高,还会有性能瓶颈。
  • 利用 redis 生成 id : 性能比较好,灵活方便,不依赖于数据库。但是,引入了新的组件造成系统更加复杂,可用性降低,编码更加复杂,增加了系 统成本。
  • Twitter的snowflake算法 :即雪花算法

16.6 数据库实际场景题

        一个6亿的表a,一个3亿的表b,通过外间tid关联,你如何最快的查询出满足条件的第50000到第50200中的这200条数据记录。

  1. 如果A表TID是自增长,并且是连续的,B表的ID为索引
    select * from a,b where a.tid = b.id and a.tid>500000 limit 200;
  2. 如果A表的TID不是连续的,那么就需要使用覆盖索引.TID要么是主键, 要么是辅助索引,B表ID也需要有索引。
    select * from b , (select tid from a limit 50000,200) a where b.id = a .t id;

17. 存储过程

  • 概念:
            一组为了完成特定功能的 SQL 语句集,存储在数据库中,经过第一 次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参 数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。

  • 语法:

CREATE PROCEDURE 存储过程名()
 
BEGIN
 			<存储过程体>
END;

18. 存储过程优化思路:

  1. 尽量利用一些 sql 语句来替代一些小循环,例如聚合函数,求平均函数等。
  2. 中间结果存放于临时表,加索引。
  3. 少使用游标。 sql 是个集合语言,对于集合运算具有较高性能。而 cursors 是过程运算。比如对一个 100 万行的数据进行查询。游标需要读表 100 万次,而不使用游标则只需要少量几次读取。
  4. 事务越短越好。 sqlserver 支持并发操作。如果事务过多过长,或者隔离级别过高,都会造成并发操作的阻塞,死锁。导致查询极慢, cpu 占用率极低。
  5. 使用 try-catch 处理错误异常。
  6. 查找语句尽量不要放在循环内。

你可能感兴趣的:(面试,java,mysql,sql,数据库)