面试不再尬聊的Mysql数据库优化方案

article/2025/8/23 7:12:05

点赞多大胆,就有多大产!有支持才有动力!将技术分享给每一个技术使用者和爱好者!

干货满满,摆好姿势,点赞发车!

 前言

数据库优化是一个老生常谈的问题,刚入门的小白或者工作N年的光头对这个问题应该都不陌生,你要面试一个中高级工程师那么他就想"哥俩好"一样那么粘,面试官肯定会问这个问题,这篇文章我们就和它哥俩好!而且这个问题就是一个送分题,数据库的优化方案基本就是那些,答案也都是固定的,大家只要好好准备这个问题就不会住你,可以在面试中安排面试官,不然就被面试官安排!话不多说下边就针对数据库优化展开讲!

相关文章

《MySQL索引从零上手使用》

《MySQL索引数据结构,看看什么是B+树吧》

《基于MyCat实现MySQL读写分离》

《基于MyCat实现MySQL数据拆分》

面试开始

小伙子看你简历上写了Mysql,数据库优化了解吗?

摸摸头之后笑着说数据库优化不是很了解嘿嘿~~~,这时和蔼的面试官头上出现了一抹红!

如果这时你正好想到了我这篇文章,那么你就会说数据库优化方面我还是很有研究的,请您听我慢慢道来......

首先

面试官我想解释一下为什么做数据库优化(这个你心里知道就好了,面试的时候就不要说了)

  • 系统的数据都从数据库上来,数据库的吞吐量和速度一定程度决定系统的并发和响应速度
  • 系统运行与数据量成正比,数据读处理尤其是查询自然就慢
  • Mysql数据库的数据最终在磁盘上持久化存储,读写不如Redis等这些内存数据库

其次

面试官大人我想说一下数据库优化一般从以下几个方面来:

  • 数据库设计:数据表设计遵循三范式,使用合适的数据类型,使用合适的存储引擎
  • 适当创建索引
  • 数据库扩展:数据库的分表分库,读写分离等
  • SQL语句优化等

接下来我们一一说明解释

数据库设计

数据库设计3范式

数据库设计范式如果要满足N范式必须要先满足N-1范式

第一范式1NF:字段原子性

第一范式简单的说就是表中的字段是最小不可再分的,我们下边举个例子,我们看到以下一张用户表。里边的字段是不可再分的,这样就符合第一范式的原子性,可能有些朋友会疑问,这个地址还可以分成省份、城市、区/县三个字段,是的!如果是一个电商项目它需要再分,那么就不符合第一范式,所以具体还是看项目的需求,没有固定标准,在项目需求中它的设计已不可再分那么就符合第一范式!

第二范式2NF: 消除对主键的部分依赖

2NF的使用是需要满足1NF为前提,在表中添加一个业务字段,而主键不用来做业务处理,比如我们的商品表有商品id,商品id为商品的主键,但是需要创建一个商品编号列来专门处理业务,因为id太敏感,我们处理业务都是用商品编号来处理,比如展示商品时展示编号等等!

第三范式3NF:在2NF的基础上添加外键

3NF的使用必须满足2NF,要求表中的每一列只与主键直接相关而不是间接相关,(表中的每一列只能依赖于主键),比如下面的例子,订单表中有客户相关信息,在分离出客户表之后,订单表中只需要有一个用户id即可(外键),而不能有其他的客户信息。因为其他的客户信息直接关联于用户id,而不是直接与订单id直接相关。如下图所示:

分离之后:

三大范式只是一般设计数据库的基本理念,可以建立冗余较小、结构合理的数据库。如果有特殊情况,当然要特殊对待,数据库设计最重要的是看需求跟性能,需求>性能>表结构。所以不能一味的去追求范式建立数据库!需求才是粑粑

数据类型

尽量使用可以正确存储数据的最小数据类型

更小的数据类型意味着更快,占用更少的磁盘,内存、缓存和处理时间

尽量使用整型表示字符串

因为字符集和校对规则,使处理字符比整型更复杂,比如:我们使用数据库内置的datetime类型存储时间而不是字符类型,我们使用整型存储ip而不是直接将ip字符串存到数据库中

尽可能使用not null

这个值是很烦人的,建字段时请尽量指定是否非空,NULL使得索引,统计,比较都变得更复杂,而且索引尽量不要创建到可以为null的字段上

字符串类型

VARCHAR是可变长字符串

比定长字符串(CHAR)更节省空间,仅使用必要的空间另外VARCHAR需要额外字节记录字符串长度(不同情况需要字节数不同)

CHAR类型是定长字符串

开发中基本很少用(一些公司甚至基本上不考虑这种类型了),注意:字符串长度定义不是字节数,是字符数

日期和时间类型

datetime

使用8字节存储空间,保存从1001年到9999年的秒数。与时区无关,默认情况下,Mysql以一种可排序的格式显示它的值,例如:"2018-10-14 22:30:08"

timestamp

只使用4字节存储,保存1970年1月1日午夜以来的秒数,依赖于系统时区,和UNIX时间戳相同,转换函数分别为FROM_UNIXTIME()和UNIX_TIMESTAMP(),可以设置根据当前时间戳更新,比如我们熟悉的update_time字段

整数类型

UNSIGNED

属性表示不允许负值,可以使得正数的上限提高一倍,比如tinyint+unsigned可以使原本的-128~127的范围变为0~255

tinyint

我们一般用它存储状态值而不要用int,如果是Boolean类型,那么tinyint(1)当值为1和0时,查询结果自动转为true和false,条件参数相应的也可以直接传入true和false即可

INT(11)

不会限制值的范围,只是规定了一些客户端工具用来显示的字符的个数,所以对于存储和计算来说INT(11)和INT(1)相同

IP地址

实际上是32位无符号整数,用INT存储,Mysql提供转换函数为INET_ATON()和INET_NTOA()

小数

decimal不会损失精度,存储空间会随数据的增大而增大。double占用固定空间,较大数的存储会损失精度,通常存金额用decimal(11,2),这表示整数部分和小数部分分别为9位和2位注意!,当然可以根据具体的金额大小选择长度,注意这时候对应的java中用BigDecimal类来处理运算时要仔细,因为加减法和比较跟平常不一样

存储引擎

介绍

数据库存储引擎是数据库底层组件,数据库管理系统使用数据引擎进行创建、查询、更新和删除数据操作。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎还可以获得特定的功能。我们可以通过SHOW ENGINES;

InnoDB存储引擎

InnoDB越做越好从MySQL5.5版本之后,MySQL的默认内置存储引擎已经是InnoDB,主要特点有

  1. 容灾恢复性比较好
  2. 支持事务,默认事务隔离界别为可重复读
  3. 使用的锁粒度为行锁,可以支持更高的并发
  4. 支持外键
  5. 配合一些热备工具可以支持在线热备份
  6. 在InnoDB中存在着缓冲管理,通过缓冲池,将索引和数据全部缓存起来,加快查询的速度
  7. 对于InnoDB类型的表,其数据的物理组织形式是聚簇表。所有的数据按照主键来组织。根据主键进行排序,数据和索引放在一块,都位于B+数的叶子节点上

MyISAM存储引擎

在5.5版本之前,MyISAM是MySQL的默认存储引擎,该存储引擎并发性差,不支持事务,所以使用场景比较少,主要特点有

  1. 不支持事务
  2. 不支持外键,如果强行增加外键,不会提示错误,只是外键不其作用
  3. 对数据的查询缓存只会缓存索引,不会像InnoDB一样缓存数据,而且是利用操作系统本身的缓存
  4. 默认的锁粒度为表级锁,所以并发度很差,加锁快,锁冲突较少,所以不太容易发生死锁
  5. 支持全文索引(MySQL5.6之后,InnoDB存储引擎也对全文索引做了支持),但是MySQL的全文索引基本不会使用,对于全文索引,现在有其他成熟的解决方案,比如:ElasticSearch,Solr,Sphinx等
  6. 数据库所在主机如果宕机,MyISAM的数据文件容易损坏,而且难恢复

MEMORY存储引擎

将数据存在内存中,和市场上的Redis,memcached等思想类似,为了提高数据的访问速度,主要特点有

  1. 支持的数据类型有限制,不支持TEXT和BLOB类型,对于字符串类型的数据,只支持固定长度的行,VARCHAR会被自动存储为CHAR类型
  2. 支持的锁粒度为表级锁。所以,在访问量比较大时,表级锁会成为MEMORY存储引擎的瓶颈
  3. 由于数据是存放在内存中,所以在服务器重启之后,所有数据都会丢失
  4. 查询的时候,如果有用到临时表,而且临时表中有BLOB,TEXT类型的字段,那么这个临时表就会转化为MyISAM类型的表,性能会急剧降低

ARCHIVE存储引擎

ARCHIVE存储引擎适合的场景有限,由于其支持压缩,故主要是用来做日志,流水等数据的归档,主要特点有

  1. 支持Zlib压缩,数据在插入表之前,会先被压缩
  2. 仅支持SELECT和INSERT操作,存入的数据就只能查询,不能做修改和删除;
  3. 只支持自增键上的索引,不支持其他索引

CSV存储引擎

数据中转试用,主要特点有

  1. 其数据格式为.csv格式的文本,可以直接编辑保存
  2. 导入导出比较方便,可以将某个表中的数据直接导出为csv,试用Excel办公软件打开

选择依据

如果没有特殊需求默认使用InnoDB引擎即可

MyISAM:以读写插入为主的应用程序,比如博客系统、新闻门户网站。

Innodb:更新(删除)操作频率也高,或者要保证数据的完整性;并发量高,支持事务和外键保证数据完整性。比如OA自动化办公系统

索引

已为客官备好,轻点哦《这小伙子把MySQL索引使用讲的真明白,真好,快来戳他》

索引数据结构在这在这《搞懂MySQL数据库索引数据结构这一篇足够从此不再萌萌哒》

MySQL读写分离

点一下就会《看了这篇文章觉得MySQL读写分离这么简单》

MySQL分表分库

一样点一下就成《手把手基于Mycat实现MySQL数据拆分》

SQL优化

这里列举出来一些用过的,看到的欢迎大家评论区补充讨论

1、查询尽量避免全表扫描,首先考虑在where、order by字段上添加索引

2、避免在where字段上使用NULL值,所以在设计表时尽量使用NOT NULL约束,有些数据会默认为NULL,可以设置默认值为0或者-1

3、避免在where子句中使用!=或<>操作符,Mysql只对<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE使用索引

4、避免在where中使用OR来连接条件,否则可能导致引擎放弃索引来执行全表扫描,可以使用UNION进行合并查询

      select id from t where num = 30 union select id from t where num = 40;

5、尽量避免在where子句中进行函数或者表达式操作

6、最好不要使用select * from t,用具体的字段列表代替"*",不要返回用不到的任何字段

7、in 和 not in 也要慎用,否则会导致全表扫描,如

select id from t where num IN(1,2,3)如果是连续的值建议使用between and,select id from t where between 1 and 3;

8、select id from t where col like %a%;模糊查询左侧有%会导致全表检索,如果需要全文检索可以使用全文搜索引擎比如es,slor

9、limit offset rows关于分页查询,尽量保证不要出现大的offset,比如limit 10000,10相当于对已查询出来的行数弃掉前10000行后再取10行,完全可以加一些条件过滤一下(完成筛选),而不应该使用limit跳过已查询到的数据。这是一个==offset做无用功==的问题。对应实际工程中,要避免出现大页码的情况,尽量引导用户做条件过滤

关注本系列文章的朋友应该发现,这里的未完待续已经消失,我们的MySQL优化就告一段落,主要从数据库设计、索引、数据库拆分和SQL语句上进行优化,更多优化方案希望大家通过评论区留言!


 路漫漫其修远兮,吾将上下而求索


http://chatgpt.dhexx.cn/article/blyUBWZu.shtml

相关文章

java系统性能优化之mysql数据库优化

java开发的应用系统经常面临系统响应时间过长的情况&#xff0c;可能的原因有很多方面&#xff0c;比如网络延迟、代码逻辑不合理&#xff0c;数据量太大、架构设计不合理、慢查询等。在优化的时候不能一上来就扑倒sql调优上&#xff0c;要整体查看性能损耗最大的地方在哪里&am…

数据库优化之中间表

过一段时间回看之前项目的数据库设计都忍不住吐槽&#xff0c;这谁写的&#xff08;我自己&#xff09;&#xff0c;当然也说明自己进步了哈。 本篇主要从性能和编码方便的角度来看中间表的使用。 昨天看原来写的数据库就发现了问题&#xff01;背单词app&#xff0c;单词书和…

浙江工业大学2023考研计算机学硕经验贴

文章目录 前言经验分享作息数学英语政治408 总体建议吐槽资源分享后面就是复试了选导师最后 前言 再开始前&#xff0c;先说一下自身情况&#xff0c;本人本科是浙江万里学院毕业的&#xff0c;同时也是一名二战生&#xff0c;一战的时候报的也是浙工大计算机学硕&#xff0c;…

杭电计算机研究生复试题

一、数据结构 线性存储和链式存储优缺点比较 1.1. 线性表的存储结构&#xff0c;优缺点 顺序存储结构可以直接存取数据元素&#xff0c;方便灵活、效率高&#xff0c;但插入、删除操作时将会引起元素的大量移动&#xff0c;因而降低效率。 链接存储结构中内存采用动态分配&am…

java 函数概述

函数 函数的定义函数调用函数分类局部变量方法重载函数递归 函数的定义 Java中函数也叫方法&#xff0c;是定义在类中的一段独立的代码块&#xff0c;用来实现某个功能&#xff1b;作用是提高代码的复用性和可读性。 语法格式&#xff1a; 修饰符 返回值类型 函数名(形式参数…

java中函数的应用。

我们把函数的特点和定义说完之后&#xff0c;我们来说说java中函数的基本应用。我们在编写程序其实就是在不断的实现功能&#xff0c;而java中最小的功能单元就是函数&#xff0c;所以我们日后再定义功能&#xff0c;都定义在一个独立的函数中去&#xff0c;而不要再乱七八糟塞…

Java函数总结

一.什么是函数&#xff1a; 为了解决某一特定问题&#xff0c;具有名称的的代码集合。JAVA函数也可以叫做方法&#xff0c;要调用方法可以通过对象去调用方法&#xff08;如果方法是非静态的&#xff09;&#xff0c;也可以直接用类名去调用方法&#xff08;如果方法是静态的&a…

JAVA方法(函数)的概念

JAVA中函数的概念&#xff0c;什么是函数&#xff1f; 答&#xff1a;函数英文称function,单一或相关联功能用来实现指定 要求功能的代码块&#xff0c;就是函数&#xff0c;函数在项目组可以直接进行调用且实现独立的功能&#xff0c;应对不同的实现需求的各种实现方法&#x…

Java方法(函数)

文章目录 Java方法(函数)一、方法介绍二、方法的定义和调用格式1. 快速入门2. Debug查看方法的执行流程3. 方法调用内存图解4. 带参数方法的定义和调用1&#xff09;定义和调用格式2&#xff09;形参和实参 5. 带返回值方法的定义和调用6. 方法通用定义格式 三、方法常见问题四…

java中的函数(概述)

java中的函数是比较重要的一个知识点。那么函数到底是什么呢&#xff0c;我们可以通过几点来进行学习&#xff0c;第一个是定义&#xff0c;第二个是特点&#xff0c;第三个是应用&#xff0c;第四个是重载。其中最重要的当然是函数的应用。定义和特点是为了入门所应用的&#…

JAVA函数(方法)

函数的概念&#xff1a; 函数是定义在类中的一段独立的代码块&#xff0c;用来实现某个功能。Java中&#xff0c;函数又被称为方法。 函数的主要作用是为了提高代码的复用性。 函数都是在栈内存中运行&#xff1b;运行的函数处在栈顶。 函数格式&#xff1a;修饰符 返回…

java函数

函数&#xff08;function&#xff09;&#xff1a; 函数是什么&#xff1f; 函数就是具有名称的特定功能代码的集合。 为什么使用函数&#xff1a; 提高代码的复用度 Java中如何定义函数 访问修饰符 [static] 返回值的类型 函数名称([形式参数列表]) { // 函数体 由一行或者…

函数总结:

–函数是什么&#xff1a; 函数是封装了具备特定功能的一段代码块&#xff0c;具备特定功能的代码集合。 –为什么使用函数&#xff1a; 解决重复性代码问题&#xff0c;提高代码的复用度。–函数基本格式&#xff1a; 访问修饰符 [static] 返回值的类型 函数名称([形式参…

java 基础——函数(方法)

函数基本定义、语法 首先我们先要了解什么是函数&#xff1f; 函数的定义&#xff1a;在类中&#xff0c;有特定功能的一段独立代码块 说人话&#xff1a;简单来说就是&#xff0c;在一个类&#xff08;一个 .java 文件&#xff09;里面&#xff0c;一段有自己存在的意义&am…

云上见!操作系统开源社区重磅发布!

凌云时刻 极鲜速递 导读&#xff1a;2020 云栖大会「系统软件开源及生态专场」聚焦云时代系统软件技术的发展及开源生态面临的机遇和挑战&#xff0c;并将进行操作系统开源社区的重磅发布。 作者 | 阿里云操作系统来源 | 云巅论剑 2020 云栖大会将在 9 月 17 日 — 9 月 18 日…

万字干货:阿里巴巴是怎么做大数据算法应用测试的? | 凌云时刻

凌云时刻 洞见 导读&#xff1a;随着最近几年数据计算力与机器智能算法的兴起&#xff0c;大数据应用在各个行业也不断涌现。测试技术作为工程技术的一部分&#xff0c;也在同步演进。在 DT 时代&#xff0c;如何测试和保障一个基于大数据的应用的软件质量&#xff0c;成为测试…

在中国在行其道的智慧城市,为何折戟多伦多? | 凌云时刻

凌云时刻 洞见 导读&#xff1a;谷歌的母公司Alphabet于2017年开始&#xff0c;致力于将多伦多的Quayside社区改造成未来主义社区&#xff0c;承诺投入超过5000万美元用于使用技术减少交通拥放和垃圾填埋场。但是由于数据隐私问题&#xff0c;该计划迅速引发了争议&#xff0c…

应云而生,原力觉醒——解读云原生基础设施 | 凌云时刻

凌云时刻 极鲜速递 导读&#xff1a;云原生是云计算领域的热点之一。就像 “一千个人眼里有一千个哈姆雷特”&#xff0c;大家对"云原生"的定义也见仁见智。本文将介绍云原生应用架构和生命周期管理的进化方向。 作者 | 易立 来源 | 凌云时刻&#xff08;微信号&…

从架构到代码:软件开发的七个新趋势 | 凌云时刻

凌云时刻 洞见 导读&#xff1a;本文根据阿里云原生团队资深技术专家陈立兵 (花名&#xff1a;雷卷)的直播整理而成&#xff0c;从领域驱动设计&#xff08;DDD&#xff09;、Reactive、Service Mesh和代码智能等几个方面展开&#xff0c;聊一聊他眼里的软件开发的发展趋势。 …

桌面版IDE将迎终结,Github发布代码空间Codespaces | 凌云时刻

凌云时刻 洞见 导读&#xff1a;2020年了&#xff0c;你拿啥写码呢&#xff1f; 作者 | 马超 来源 | 凌云时刻&#xff08;微信号&#xff1a;linuxpk&#xff09; Satellite 2020 5月7日&#xff0c;受疫情的影响&#xff0c;全球最大的开源社区GitHub也采用了线上的方式举办…