数据库面经4

SQL优化有什么思路?

  • 创建索引

    • 要尽量避免全表扫描,首先应考虑where及order by 涉及的列上建立索引。

    • 在经常需要进行检索的字段上创建索引。

    • 在一个表的索引数最好不要超过六个。

  • 避免在索引上使用计算

    • 在where字句中,如果索引列是计算或者函数的一部分,DBMS的优化器将不会使用索引而使用全表查询,函数 属于计算的一种,同事在in和exists中通常情况下使用exists,因为in不走索引。

  • 尽量将多条sql语句压缩到一句sql中

    • 每次执行sql的时候都要建立网络连接、进行权限校验、进行sql语句的查询优化、发送执行结果、这个过程是非常耗时的,因此应该避免过多的执行sql语句,能够压缩一句sql执行的语句就不要多条来执行。

  • 用where字句替换having字句

    • 避免使用having字句,因为having只会在检索出所有记录之后才对结果进行过滤,而where则是在聚合前刷选记录,如果能通过where字句限制记录的数目,那就能减少这方面的开始小。

  • 查询select语句优化

  • 任何地方都不要使用selct * form t,要具体的字段列表代替* ,不要返回用不到的字段。

  • 应尽量避免在where子句中进行null值判断,否则将导致引擎放弃使用索引而进行全表扫描。

  • 更新update语句优化

  • 如果只更新一两个字段,就不要更新全部字段,否则会导致频繁调用引起明细的新能消耗,带来大量日志。

  • 插入inset 语句优化

  • 在新建临时表时,如果一次性插入数据量很大,那么可以使用selcet into 代替create table,避免造成大量log,日高数据。

  • 大表优化:当MySQL单表记录数过大时,数据库的CRUD性能会明显下降,一些常见的优化措施如下:

    • 限定数据的范围:务必禁止不待任何限制数据范围条件的搜索语句。比如:我们当前用户在查询订单历史的时候,我们可以控制在一个月的范围内;

    • 读写分离:经典的数据库拆分方案,主库负责写,从副库负责读

    • 垂直分区:根据数据库里面的数据表的相关性进行拆分。例如,用户表中既有用户的登录信息又有用户的基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库。简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分称为多个表。

      • 优点:可以使得列数据变小,在查询时减少读取的Block数,减少I/O次数。此外,垂直分布可以简化表的结构,易于维护。

      • 缺点:主键会出现冗余,需要管理冗余列。垂直分区会让事务变得更复杂。

    • 水平分区:保持数据表结构不变,通过某种策略存储数据分片。这样每一片数据分散到不同的表或者库中,达到了分布式的目的。

      • 优点:支持非常大的数据量存储,应用端改造也小

      • 缺点:分片事务难以解决,跨结点的jion性能较差、逻辑复杂

锁机制与InnoDB锁算法

InnoDB存储引擎的锁的算法有三种:

  • Record lock:单个行记录上的锁

  • Gap lock:间隙锁,锁定一个范围,不包括记录本身

  • Next-key lock:record+gap 锁定一个范围,包含记录本身

相关知识点:

  1. innodb对于行的查询使用next-key lock

  2. Next-locking keying为了解决Phantom Problem幻读问题

  3. 当查询的索引含有唯一属性时,将next-key lock降级为record key

  4. Gap锁设计的⽬的是为了阻⽌多个事务将记录插⼊到同一范围内,⽽这会导致幻读问题的产生

  5. 有两种方式显式关闭gap锁:(除了外键约束和唯一性检查外,其余情况仅使用record lock) A. 将事务隔离级别设置为RC B. 将参数innodb_locks_unsafe_for_binlog设置为1

项用中使用到外键了吗?外键作用?使用外键要注意些什么问题?

外键的作用:外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。

优点:能够由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器宕机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。

缺点:性能差,当每次插入数据时,当存在外键约束的时候,每次都要扫描此记录是否合格,一般还不止一个字段有外键,这样扫描数量是成级数的增长。

注意点:

  • 父表和子表都必须使用相同的存储引擎,而且禁止使用临时表

  • 数据库存储引擎只能为InnoDB(MySQL)

  • 外键列与参照列的数据类型必须相同

猜你喜欢

转载自blog.csdn.net/slave_of_life/article/details/130650150