数据库性能优化八大方案

毫不夸张的说咱们后端工程师,无论在哪家公司,呆在哪个团队,做哪个系统,遇到的第一个让人头疼的问题绝对是数据库性能问题。如果我们有一套成熟的方法论,能让大家快速、准确的去选择出合适的优化方案,我相信能够快速准备解决咱么日常遇到的80%甚至90%的性能问题。

从解决问题的角度出发,我们得先了解到问题的原因;其次我们得有一套思考、判断问题的流程方式,让我们合理的站在哪个层面选择方案;最后从众多的方案里面选择一个适合的方案进行解决问题,找到一个合适的方案的前提是我们自己对各种方案之间的优缺点、场景有足够的了解,没有一个方案是完全可以通吃通用的,软件工程没有银弹。

下文是我工作多年以来,曾经使用过的八大方案,结合了平常自己学习收集的一些资料,以系统、全面的方式整理成了这篇博文,也希望能让一些有需要的同行在工作上、成长上提供一定的帮助。

为什么数据库会慢?

无论是关系型数据库还是 NoSQL,任何存储系统决定于其查询性能的主要有三种:

  • 查找的时间复杂度
  • 数据总量
  • 高负载

而决定于查找时间复杂度主要有两个因素:

  • 查找算法
  • 存储数据结构

无论是哪种存储,数据量越少,自然查询性能就越高,随着数据量增多,资源的消耗(CPU、磁盘读写繁忙)、耗时也会越来越高。

从关系型数据库角度出发,索引结构基本固定是B+Tree,时间复杂度是O(log n),存储结构是行式存储。因此咱们对于关系数据库能优化的一般只有数据量。

而高负载造成原因有高并发请求、复杂查询等,导致CPU、磁盘繁忙等,而服务器资源不足则会导致慢查询等问题。该类型问题一般会选择集群、数据冗余的方式分担压力。

应该站在哪个层面思考优化?

从上图可见,自顶向下的一共有四层,分别是硬件、存储系统、存储结构、具体实现。

层与层之间是紧密联系的,每一层的上层是该层的载体;因此越往顶层越能决定性能的上限,同时优化的成本也相对会比较高,性价比也随之越低。

以最底层的具体实现为例,那么索引的优化的成本应该是最小的,可以说加了索引后无论是 CPU 消耗还是响应时间都是立竿见影降低。

然而一个简单的语句,无论如何优化加索引也是有局限的,当在具体实现这层没有任何优化空间的时候就得往上一层【存储结构】思考,思考是否从物理表设计的层面出发优化(如分库分表、压缩数据量等),如果是文档型数据库得思考下文档聚合的结果。

如果在存储结构这层优化得没效果,得继续往再上一次进行考虑,是否关系型数据库应该不适合用在现在得业务场景?

如果要换存储,那么得换什么样的 NoSQL?所以咱们优化的思路,出于性价比的优先考虑具体实现,实在没有优化空间了再往上一层考虑。

当然如果公司有钱,直接使用钞能力,绕过了前面三层,这也是一种便捷的应急处理方式。

该篇文章不讨论顶与底的两个层面的优化,主要从存储结构、存储系统中间两层的角度出发进行探讨。

八大方案总结

数据库的优化方案核心本质有三种:减少数据量、用空间换性能、选择合适的存储系统

这也对应了开篇讲解的慢的三个原因:数据总量、高负载、查找的时间复杂度。

这里大概解释下收益类型:短期收益,处理成本低,能紧急应对,久了则会有技术债务;长期收益则跟短期收益相反,短期内处理成本高,但是效果能长久使用,扩展性会更好。

静态数据意思是,相对改动频率比较低的,也无需过多联表的,where 过滤比较少。动态数据与之相反,更新频率高,通过动态条件筛选过滤。

减少数据量

减少数据量类型共有四种方案:数据序列化存储、数据归档、中间表生成、分库分表。

就如上面所说的,无论是哪种存储,数据量越少,自然查询性能就越高,随着数据量增多,资源的消耗(CPU、磁盘读写繁忙)、耗时也会越来越高。

目前市面上的 NoSQL 基本上都支持分片存储,所以其天然分布式写的能力从数据量上能得到非常的解决方案。而关系型数据库,查找算法与存储结构是可以优化的空间比较少,因此咱们一般思考出发点只有从如何减少数据量的这个角度进行选择优化,因此本类型的优化方案主要针对关系型数据库进行处理

数据归档

注意点:别一次性迁移数量过多,建议低频率多次限量迁移。

像MySQL由于删除数据后是不会释放空间的,可以执行命令OPTIMIZE TABLE释放存储空间,但是会锁表,如果存储空间还满足,可以不执行。

建议优先考虑该方案,主要通过数据库作业把非热点数据迁移到历史表,如果需要查历史数据,可新增业务入口路由到对应的历史表(库)。

在数据库以序列化存储的方式,对于一些不需要结构化存储的业务来说是一种很好减少数据量的方式,特别是对于一些M*N的数据量的业务场景,如果以M作为主表优化,那么就可以把数据量维持最多是M的量级。

另外像订单的地址信息,这种业务一般是不需要根据里面的字段检索出来,也比较适合。这种方案我认为属于一种临时性的优化方案,无论是从序列化后丢失了部份字段的查询能力,还是这方案的可优化性都是有限的。

中间表(结果表)

中间表(结果表)其实就是利用调度任务把复杂查询的结果跑出来存储到一张额外的物理表,因为这张物理表存放的是通过跑批汇总后的数据,因此可以理解成根据原有的业务进行了高度的数据压缩。

以报表为例,如果一个月的源数据有数十万,我们通过调度任务以月的维度生成,那么等于把原有的数据压缩了几十万分之一。接下来的季报和年报可以根据月报 *N 来进行统计,以这种方式处理的数据,就算三年、五年甚至十年数据量都可以在接受范围之内,而且可以精确计算得到。

那么数据的压缩比率是否越低越好?下面有一段口诀:

  • 字段越多,粒度越细,灵活性越高,可以以中间表进行不同业务联表处理。
  • 字段越少,粒度越粗,灵活性越低,一般作为结果表查询出来。

数据序列化存储

分库分表

分库分表作为数据库优化的一种非常经典的优化方案,特别是在以前 NoSQL 还不是很成熟的年代,这个方案就如救命草一般的存在。

如今也有不少同行也会选择这种优化方式,但是从我角度来看,分库分表是一种优化成本很大的方案。这里我有几个建议:

  • 分库分表是实在没有办法的办法,应放到最后选择。
  • 优先选择 NoSQL 代替,因为 NoSQL 诞生基本上为了扩展性与高性能。
  • 究竟分库还是分表?量大则分表,并发高则分库
  • 不考虑扩容,一部做到位。因为技术更新太快了,每 3-5 年一大变。

拆分方式

只要涉及到这个拆,那么无论是微服务也好,分库分表也好,拆分的方式主要分两种:垂直拆分、水平拆分。

垂直拆分更多是从业务角度进行拆分,主要是为了降低业务耦合度;此外以 SQL Server 为例,一页是 8KB 存储,如果在一张表里字段越多,一行数据自然占的空间就越大,那么一页数据所存储的行数就自然越少,那么每次查询所需要 IO 则越高因此性能自然也越慢;因此反之,减少字段也能很好提高性能。

之前我听说某些同行的表有 80 个字段,几百万的数据就开始慢了。

水平拆分更多是从技术角度进行拆分,拆分后每张表的结构是一模一样的,简而言之就是把原有一张表的数据,通过技术手段进行分片到多张表存储,从根本上解决了数据量的问题。

路由方式

进行水平拆分后,根据分区键(sharding key)原来应该在同一张表的数据拆解写到不同的物理表里,那么查询也得根据分区键进行定位到对应的物理表从而把数据给查询出来。

路由方式一般有三种:区间范围、Hash、分片映射表

每种路由方式都有自己的优点和缺点,可以根据对应的业务场景进行选择。区间范围根据某个元素的区间的进行拆分,以时间为例子,假如有个业务我们希望以月为单位拆分那么表就会拆分像 table_2022-04,这种对于文档型、ElasticSearch 这类型的 NoSQL 也适用,无论是定位查询,还是日后清理维护都是非常的方便的。

那么缺点也明显,会因为业务独特性导致数据不平均,甚至不同区间范围之间的数据量差异很大。Hash 也是一种常用的路由方式,根据 Hash 算法取模以数据量均匀分别存储在物理表里,缺点是对于带分区键的查询依赖特别强,如果不带分区键就无法定位到具体的物理表导致相关所有表都查询一次,而且在分库的情况下对于 Join、聚合计算、分页等一些 RDBMS 的特性功能还无法使用。

一般分区键就一个,假如有时候业务场景得用不是分区键的字段进行查询,那么难道就必须得全部扫描一遍?其实可以使用分片映射表的方式。简单来说就是额外有一张表记录额外字段与分区键的映射关系。

举个例子,有张订单表,原本是以 UserID 作为分区键拆分的,现在希望用 OrderID 进行查询,那么得有额外得一张物理表记录了 OrderID 与 UserID 的映射关系。因此得先查询一次映射表拿到分区键,再根据分区键的值路由到对应的物理表查询出来。

可能有些朋友会问,那这映射表是否多一个映射关系就多一张表,还是多个映射关系在同一张表?我优先建议单独处理,如果说映射表字段过多,那跟不进行水平拆分时的状态其实就是一致的,这又跑回去的老问题。

用空间换性能

该类型的两个方案都是用来应对高负载的场景,方案有以下两种:分布式缓存、一主多从

与其说这个方案叫用空间换性能,我认为用空间换资源更加贴切一些。因此两个方案的本质主要通数据冗余、集群等方式分担负载压力。

对于关系型数据库而言,因为他的ACID特性让它天生不支持写的分布式存储,但是它依然天然的支持分布式读。

分布式缓存

缓存层级可以分好几种:客户端缓存、API服务本地缓存和分布式缓存

咱们这次只聊分布式缓存。一般我们选择分布式缓存系统都会优先选择 NoSQL 的键值型数据库,例如 Memcached、Redis,如今 Redis 的数据结构多样性,高性能,易扩展性也逐渐占据了分布式缓存的主导地位。

缓存策略也主要有很多种:Cache-Aside、Read/Wirte-Through、Write-Back,咱们用得比较多的方式主要 Cache-Aside,具体流程可看下图:

我相信大家对分布式缓存相对都比较熟悉了,但是我在这里还是有几个注意点希望提醒一下大家:

避免滥用缓存

缓存应该是按需使用,从 28 法则来看,80% 的性能问题由主要的 20% 的功能引起。

滥用缓存的后果会导致维护成本增大,而且有一些数据一致性的问题也不好定位。特别像一些动态条件的查询或者分页,key 的组装是多样化的,量大又不好用 keys 指令去处理,当然我们可以用额外的一个 key 把记录数据的 key 以集合方式存储,删除时候做两次查询,先查 Key 的集合,然后再遍历 Key 集合把对应的内容删除。

这一顿操作下来无疑是非常废功夫的,谁弄谁知道。

避免缓存击穿

当缓存没有数据,就得跑去数据库查询出来,这就是缓存穿透。

假如某个时间临界点数据是空的例如周排行榜,穿透过去的无论查找多少次数据库仍然是空,而且该查询消耗 CPU 相对比较高,并发一进来因为缺少了缓存层的对高并发的应对,这个时候就会因为并发导致数据库资源消耗过高,这就是缓存击穿。

数据库资源消耗过高就会导致其他查询超时等问题。该问题的解决方案也简单,对于查询到数据库的空结果也缓存起来,但是给一个相对快过期的时间。

有些同行可能又会问,这样不就会造成了数据不一致了么?一般有数据同步的方案像分布式缓存、后续会说的一主多从、CQRS,只要存在数据同步这几个字,那就意味着会存在数据一致性的问题,因此如果使用上述方案,对应的业务场景应允许容忍一定的数据不一致。

不是所有慢查询都适用

一般来说,慢的查询都意味着比较吃资源的(CPU、磁盘I/O)。  

举个例子,假如某个查询功能需要 3 秒时间,串行查询的时候并没什么问题,我们继续假设这功能每秒大概 QPS 为 100,那么在第一次查询结果返回之前,接下来的所有查询都应该穿透到数据库,也就意味着这几秒时间有 300 个请求到数据库,如果这个时候数据库 CPU 达到了 100%,那么接下来的所有查询都会超时,也就是无法有第一个查询结果缓存起来,从而还是形成了缓存击穿。

一主多从

常用的分担数据库压力还有一种常用做法,就是读写分离、一主多从。

咱们都是知道关系型数据库天生是不具备分布式分片存储的,也就是不支持分布式写,但是它天然的支持分布式读。一主多从是部署多台从库只读实例,通过冗余主库的数据来分担读请求的压力,路由算法可有代码实现或者中间件解决,具体可以根据团队的运维能力与代码组件支持视情况选择。

一主多从在还没找到根治方案前是一个非常好的应急解决方案,特别是在现在云服务的年代,扩展从库是一件非常方便的事情,而且一般情况只需要运维或者 DBA 解决就行,无需开发人员接入。

当然这方案也有缺点,因为数据无法分片,所以主从的数据量完全冗余过去,也会导致高的硬件成本。从库也有其上限,从库过多了会主库的多线程同步数据的压力。

选择合适的存储系统
NoSQL 主要以下五种类型:键值型、文档型、列型、图型、搜素引擎

不同的存储系统直接决定了查找算法、存储数据结构,也应对了需要解决的不同的业务场景。NoSQL的出现也解决了关系型数据库之前面临的难题(性能、高并发、扩展性等)。

例如,ElasticSearch 的查找算法是倒排索引,可以用来代替关系型数据库的低性能、高消耗的 Like 搜索(全表扫描)。而 Redis 的 Hash 结构决定了时间复杂度为 O(1),还有它的内存存储,结合分片集群存储方式以至于可以支撑数十万 QPS。

因此本类型的方案主要有两种:CQRS、替换(选择)存储,这两种方案的最终本质基本是一样的主要使用合适存储来弥补关系型数据库的缺点,只不过切换过渡的方式会有点不一样。

CQRS

CQS(命令查询分离)指同一个对象中作为查询或者命令的方法,每个方法或者返回的状态,要么改变状态,但不能两者兼备

讲解 CQRS 前得了解 CQRS,有些小伙伴看了估计还没不是很清晰,我这里用通俗的话解释:某个对象的数据访问的方法里,要么只是查询,要么只是写入(更新)。

而 CQRS(命令查询职责分离)基于 CQS 的基础上,用物理数据库来写入(更新),而用另外的存储系统来查询数据。

因此我们在某些业务场景进行存储架构设计时,可以通过关系型数据库的 ACID 特性进行数据的更新与写入,用 NoSQL 的高性能与扩展性进行数据的查询处理,这样的好处就是关系型数据库和 NoSQL 的优点都可以兼得,同时对于某些业务不适于一刀切的替换存储的也可以有一个平滑的过渡。

从代码实现角度来看,不同的存储系统只是调用对应的接口 API,因此 CQRS 的难点主要在于如何进行数据同步。

数据同步方式

一般讨论到数据同步的方式主要是分推和拉:推指的是由数据变更端通过直接或者间接的方式把数据变更的记录发送到接收端,从而进行数据的一致性处理,这种主动的方式优点是实时性高。

拉指的是接收端定时的轮询数据库检查是否有数据需要进行同步,这种被动的方式从实现角度来看比推简单,因为推是需要数据变更端支持变更日志的推送的。

而推的方式又分两种:CDC(变更数据捕获)和领域事件。对于一些旧的项目来说,某些业务的数据入口非常多,无法完整清晰的梳理清楚,这个时候 CDC 就是一种非常好的方式,只要从最底层数据库层面把变更记录取到就可。

对于已经服务化的项目来说领域事件是一种比较舒服的方式,因为 CDC 是需要数据库额外开启功能或者部署额外的中间件,而领域事件则不需要,从代码可读性来看会更高,也比较开发人员的维护思维模式。

替换(选择)存储系统
因为从本质来看该模式与 CQRS 的核心本质是一样的,主要是要对 NoSQL 的优缺点有一个全面认识,这样才能在对应业务场景选择与判断出一个合适的存储系统。

这里我给大家介绍一本书马丁.福勒《NoSQL精粹》,这本书我重复看了好几遍,也很好全面介绍各种 NoSQL 优缺点和使用场景。

当然替换存储的时候,我这里也有个建议:加入一个中间版本,该版本做好数据同步与业务开关,数据同步要保证全量与增加的处理,随时可以重来。

业务开关主要是为了后续版本的更新做的一个临时型的功能,主要避免后续版本更新不顺利或者因为版本更新时导致的数据不一致的情况出现。

在跑了一段时间后,验证了两个不同的存储系统数据是一致的后,接下来就可以把数据访问层的底层调用替换了。如此一来就可以平滑的更新切换。

最后说一句

本文到这里就把八大方案介绍完了,这八个方案里,大部分都存在数据同步的情况,只要存在数据同步,无论是一主多从、分布式缓存、CQRS 都好,都会有数据一致性的问题导致,因此这些方案更多适合一些只读的业务场景。

当然有些写后既查的场景,可以通过过渡页或者广告页通过用户点击关闭切换页面的方式来缓解数据不一致性的情况。

最后,在这里再次提醒一句,每个方案都有属于它的应对场景,咱们只能根据业务场景选择对应的解决方案,没有通吃,没有银弹。 

更多精彩内容,关注我们▼

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/220602.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL系列(十):主从架构

一:主从架构 常见的主从架构模式有四种: 一主多从架构:适用于读大于写的场景,采用多个从库来分担数据库系统的读压力。多主架构:适用于读写参半的场景,采用多个主库来承载数据库系统整体的读写压力。多主…

可视化 Java 项目

有一定规模的 IT 公司,只要几年,必然存在大量的代码,比如腾讯,2019 年一年增加 12.9 亿行代码,现在只会更多。不管是对于公司,还是对于个人,怎么低成本的了解这些代码的对应业务,所提…

Spring Boot统一功能处理(Spring拦截器)

为什么需要Spring拦截器 原生的Spring AOP实现统一拦截有两大难点,1.定义拦截的规则难写;2.在切面类中拿到HttpSession比较难。为此Spring官方提供了拦截器帮我们解决了上面痛点。 实现登入信息验证拦截器 实现HanderInterceptor接口重写preHeadler方…

【LeetCode刷题】--172.阶乘后的零

172.阶乘后的零 方法&#xff1a; class Solution {public int trailingZeroes(int n) {int ans 0;for(int i 5;i<n;i5){for(int x i; x % 50; x/5){ans;}}return ans;} }进一步优化&#xff1a; class Solution {public int trailingZeroes(int n) {int ans 0;while (n…

【个人版】SpringBoot下Spring-Security核心概念解读【二】

Spring-Security HttpSecurity Spring-Security全局导读&#xff1a; 1、Security核心类设计 2、HttpSecurity结构和执行流程解读 3、Spring-Security个人落地篇 背景&#xff1a; Spring-Security框架的核心架构上一篇已经概述&#xff0c;展示其执行流程及逻辑&#xff0c;但…

【期末考复习向】transformer的运作机制

1.transformer的encoder运作 transformer的encoder部分包括了输入和处理2大部分。首先是输入部分inputs&#xff0c;这里初始的inputs是采用独热向量进行表示的&#xff0c;随后经过word2vec等操作把独热向量&#xff08;采用独热向量的好处就是可向量是正交的&#xff0c;可以…

re:Invent 产品体验分享:Amazon ElastiCache Serverless 缓存即时扩展功能与感受

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道&#xff09;。 文章目录 前言产品介绍产品使用步骤1.创建缓存服务2.安全组开放访问权限…

C++从bing采集各行业的企业官网信息

作为一名合格的销售&#xff0c;除了自己的人脉&#xff0c;还应该有新鲜的客户加入并发掘。不管哪行哪业&#xff0c;知彼知己&#xff0c;方才能做到百战百胜。今天我就用我们的专业技能&#xff0c;让销售获取更多同行业的公开企业信息&#xff0c;让业绩顺风顺水。 通常在C…

如何实现电脑文件夹自动备份?以下是图解教程

在当今迅猛发展的科技时代&#xff0c;电脑已经成为不可或缺的办公工具。随着使用时间的增加&#xff0c;存储在电脑中的文件数量也逐渐增多。然而&#xff0c;由于设备故障、手动误删等原因&#xff0c;文件的丢失问题成为一个不可忽视的风险。如果丢失的文件具有重要性&#…

数学learning

目录 移动平均 简单移动平均 加权移动平均 指数移动平均 矩阵求导 矩阵对标量求导 Matrix-by-scalar 标量对矩阵求导 Scalar-by-matrix 参考博客 移动平均 优化算法里面会涉及到一个知识点&#xff1a;指数移动平均。 但是为了知识的完整性&#xff0c;这里会将常见的移动…

MCU平台下一种简单的文件系统设计构想

本文介绍MCU平台下一种简单的文件系统设计构想。 在使用MCU的项目中&#xff0c;经常会涉及到一些数据的存储&#xff0c;受限于硬件&#xff0c;又不太可能直接上文件系统&#xff08;如FAT文件系统&#xff09;&#xff0c;直接指定存储地址&#xff0c;数据长度对数据进行读…

React antd如何实现<Upload>组件上传附件再次上传已清除附件缓存问题

最近遇到一个React上传组件的问题&#xff0c;即上传附件成功后&#xff0c;文件展示处仍然还有之前上传附件的缓存信息&#xff0c;需要解决的问题是&#xff0c;要把上一次上传的附件缓存在上传成功或者取消后&#xff0c;可以进行清除 经过一顿试错&#xff0c;终于解决了这…

SE考研真题总结(二)

接上条&#xff0c;今天继续更新~ SE考研真题总结&#xff08;一&#xff09;-CSDN博客文章浏览阅读340次&#xff0c;点赞6次&#xff0c;收藏11次。本帖开始分享考研真题中设计【软件工程】的部分&#xff0c;预计会出5期左右&#xff0c;敬请期待~https://blog.csdn.net/js…

EasyRecovery(数据恢复软件) 2024中文绿色无需激活版下载

EasyRecovery是一款功能强大且专业的数据恢复软件&#xff0c;软件能够对电脑误删的文件进行恢复&#xff0c;包括格式化硬盘是数据恢复、手机U盘数据恢复等&#xff0c;小编今天给大家带来的是根据官软件解压后直接使用。感兴趣的朋友快来下载使用吧。 EasyRecovery-2024mac最…

Pytorch-CNN轴承故障一维信号分类(二)

目录 前言 1 数据集制作与加载 1.1 导入数据 1.2 数据加载&#xff0c;训练数据、测试数据分组&#xff0c;数据分batch 2 CNN-2D分类模型和训练、评估 2.1 定义CNN-2d分类模型 2.2 定义模型参数 2.3 模型结构 2.4 模型训练 2.5 模型评估 3 CNN-1D分类模型和训练、评…

flink找不到隐式项

增加 import org.apache.flink.streaming.api.scala._ 即可

改进的A*算法的路径规划(2)

子节点优化选择策略 (1)子节点选择方式 为了找到从起始点到终点的路径&#xff0c;需定义一种可以选择后续节点的方式。在 A*算法中两种常见的方法为4-邻接(见图5-7(a) 和8-邻接(见图5-7(b)), 但考虑到 在复杂越野环境上&#xff0c;我们希望智能车辆允许更多的自由运动来更…

MSF学习

之前的渗透测试中 其实很少用到 cs msf 但是在实际内网的时候 可以发现 msf cs 都是很好用的 所以现在我来学习一下 msf的使用方法 kali自带msf https://www.cnblogs.com/bmjoker/p/10051014.html 使用 msfconsole 启动即可 首先就是最正常的木马生成 所以这里其实只需…

分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】

分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】 目录 分类预测 | Matlab实现DBO-SVM蜣螂算法优化支持向量机的数据分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现DBO-SVM蜣螂算法优化支持向量机的…

数理统计基础:参数估计与假设检验

在学习机器学习的过程中&#xff0c;我充分感受到概率与统计知识的重要性&#xff0c;熟悉相关概念思想对理解各种人工智能算法非常有意义&#xff0c;从而做到知其所以然。因此打算写这篇笔记&#xff0c;先好好梳理一下参数估计与假设检验的相关内容。 1 总体梳理 先从整体结…