MySQL性能优化-数据库调优有哪些维度可以选择

数据库调优的目标

简单来说,数据库调优的目的就是要让数据库运行得更快,也就是说响应的时间更快,吞吐量更大。

不过随着用户量的不断增加,以及应用程序复杂度的提升,我们很难用“更快”去定义数据库调优的目标,因为用户在不同时间段访问服务器遇到的瓶颈不同,比如双十一促销的时候会带来大规模的并发访问;还有用户在进行不同业务操作的时候,数据库的事务处理和 SQL 查询都会有所不同。因此我们还需要更加精细的定位,去确定调优的目标。

如何确定呢?一般情况下,有两种方式可以得到反馈。

用户的反馈
用户是我们的服务对象,因此他们的反馈是最直接的。虽然他们不会直接提出技术建议,但是有些问题往往是用户第一时间发现的。我们要重视用户的反馈,找到和数据相关的问题。

日志分析
我们可以通过查看数据库日志和操作系统日志等方式找出异常情况,通过它们来定位遇到的问题。

服务器资源使用监控
通过监控服务器的 CPU、内存、I/O 等使用情况,可以实时了解服务器的性能使用,与历史情况进行对比。

数据库内部状况监控
在数据库的监控中,活动会话(Active Session)监控是一个重要的指标。通过它,你可以清楚地了解数据库当前是否处于非常繁忙的状态,是否存在 SQL 堆积等。
除了活动会话监控以外,我们也可以对事务、锁等待等进行监控,这些都可以帮助我们对数据库的运行状态有更全面的认识。

对数据库进行调优,都有哪些维度可以进行选择?

我们需要调优的对象是整个数据库管理系统,它不仅包括 SQL 查询,还包括数据库的部署配置、架构等。从这个角度来说,我们思考的维度就不仅仅局限在 SQL 优化上了。

数据库优化步骤如下:

一、选择适合的 DBMS

我们之前讲到了 SQL 阵营和 NoSQL 阵营。在 RDBMS 中,常用的有 Oracle,SQL Server 和 MySQL 等。如果对事务性处理以及安全性要求高的话,可以选择商业的数据库产品。这些数据库在事务处理和查询性能上都比较强,比如采用 SQL Server,那么单表存储上亿条数据是没有问题的。如果数据表设计得好,即使不采用分库分表的方式,查询效率也不差。

除此以外,你也可以采用开源的 MySQL 进行存储,我们之前讲到过,它有很多存储引擎可以选择,如果进行事务处理的话可以选择 InnoDB,非事务处理可以选择 MyISAM。

NoSQL 阵营包括键值型数据库、文档型数据库、搜索引擎、列式存储和图形数据库。这些数据库的优缺点和使用场景各有不同,比如列式存储数据库可以大幅度降低系统的 I/O,适合于分布式文件系统和 OLAP,但如果数据需要频繁地增删改,那么列式存储就不太适用了。原因我在答疑篇已经讲过,这里不再赘述。

DBMS 的选择关系到了后面的整个设计过程,所以第一步就是要选择适合的 DBMS。如果已经确定好了 DBMS,那么这步可以跳过,但有时候我们要根据业务需求来进行选择。

二、优化表设计

RDBMS 中,每个对象都可以定义为一张表,表与表之间的关系代表了对象之间的关系。如果用的是 MySQL,我们还可以根据不同表的使用需求,选择不同的存储引擎。除此以外,还有一些优化的原则可以参考:

表结构要尽量遵循第三范式的原则(关于第三范式,我在后面章节会讲)。这样可以让数据结构更加清晰规范,减少冗余字段,同时也减少了在更新,插入和删除数据时等异常情况的发生。
如果分析查询应用比较多,尤其是需要进行多表联查的时候,可以采用反范式进行优化。反范式采用空间换时间的方式,通过增加冗余字段提高查询的效率。
表字段的数据类型选择,关系到了查询效率的高低以及存储空间的大小。一般来说,如果字段可以采用数值类型就不要采用字符类型;字符长度要尽可能设计得短一些。针对字符类型来说,当确定字符长度固定时,就可以采用 CHAR 类型;当长度不固定时,通常采用 VARCHAR 类型。

三、优化逻辑查询

建立好数据表之后,就可以对数据表进行增删改查的操作了。这时我们首先需要考虑的是逻辑查询优化,什么是逻辑查询优化呢?

SQL 查询优化,可以分为逻辑查询优化和物理查询优化。逻辑查询优化就是通过改变 SQL 语句的内容让 SQL 执行效率更高效,采用的方式是对 SQL 语句进行等价变换,对查询进行重写。重写查询的数学基础就是关系代数。

SQL 的查询重写包括了子查询优化、等价谓词重写、视图重写、条件简化、连接消除和嵌套连接消除等。

举例说明:
假设我想对商品评论表中的评论内容进行检索,查询评论内容开头为 abc 的内容都有哪些?

// Method1
SELECT comment_id, comment_text, comment_time FROM product_comment WHERE SUBSTRING(comment_text, 1,3)='abc'
//Method2
SELECT comment_id, comment_text, comment_time FROM product_comment WHERE comment_text LIKE 'abc%'

你会发现在数据量大的情况下,第二条 SQL 语句的查询效率要比前面的高很多,执行时间为前者的 1/10。

四、优化物理查询

物理查询优化是将逻辑查询的内容变成可以被执行的物理操作符,从而为后续执行器的执行提供准备。它的核心是高效地建立索引,并通过这些索引来做各种优化。

当然了索引不是万能的,我们需要根据实际情况来创建索引,那么都有哪些情况需要考虑呢?

如果数据重复度高,就不需要创建索引。通常在重复度超过 10% 的情况下,可以不创建这个字段的索引。比如性别这个字段(取值为男和女)。
要注意索引列的位置对索引使用的影响。比如我们在 WHERE 子句中对索引字段进行了表达式的计算,会造成这个字段的索引失效
要注意联合索引对索引使用的影响。我们在创建联合索引的时候会对多个字段创建索引,这时索引的顺序就很重要了。比如我们对字段 x, y, z 创建了索引,那么顺序是 (x,y,z) 还是 (z,y,x),在执行的时候就会存在差别。
要注意多个索引对索引使用的影响。索引不是越多越好,因为每个索引都需要存储空间,索引多也就意味着需要更多的存储空间。此外,过多的索引也会导致优化器在进行评估的时候增加了筛选出索引的计算时间,影响评估的效率。

查询优化器在对 SQL 语句进行等价变换之后,还需要根据数据表的索引情况和数据情况确定访问路径,这就决定了执行 SQL 时所需要消耗的资源。SQL 查询时需要对不同的数据表进行查询,因此在物理查询优化阶段也需要确定这些查询所采用的路径,具体的情况包括:

单表扫描:对于单表扫描来说,我们可以全表扫描所有的数据,也可以局部扫描。
两张表的连接:常用的连接方式包括了嵌套循环连接、HASH 连接和合并连接。
多张表的连接:多张数据表进行连接的时候,顺序很重要,因为不同的连接路径查询的效率不同,搜索空间也会不同。我们在进行多表连接的时候,搜索空间可能会达到很高的数据量级,巨大的搜索空间显然会占用更多的资源,因此我们需要通过调整连接顺序,将搜索空间调整在一个可接收的范围内。

物理查询优化是在确定了逻辑查询优化之后,采用物理优化技术(比如索引等),通过计算代价模型对各种可能的访问路径进行估算,从而找到执行方式中代价最小的作为执行计划。在这个部分中,我们需要掌握的重点是对索引的创建和使用。

五、缓存优化

因为数据都是存放到数据库中,我们需要从数据库层中取出数据放到内存中进行业务逻辑的操作,当用户量增大的时候,如果频繁地进行数据查询,会消耗数据库的很多资源。如果我们将常用的数据直接放到内存中,就会大幅提升查询的效率。

键值存储数据库可以帮我们解决这个问题。

常用的键值存储数据库有 Redis 和 Memcached,它们都可以将数据存放到内存中。

Redis和Memcached对比

持久化:从可靠性来说,Redis 支持持久化,可以让我们的数据保存在硬盘上,不过这样一来性能消耗也会比较大。而 Memcached 仅仅是内存存储,不支持持久化。
数据类型:Redis 比 Memcached 要多,它不仅支持 key-value 类型的数据,还支持 List,Set,Hash 等数据结构。

通常我们对于查询响应要求高的场景(响应时间短,吞吐量大),可以考虑内存数据库,毕竟术业有专攻。传统的 RDBMS 都是将数据存储在硬盘上,而内存数据库则存放在内存中,查询起来要快得多。不过使用不同的工具,也增加了开发人员的使用成本。

六、库级优化

库级优化是站在数据库的维度上进行的优化策略,比如控制一个库中的数据表数量。另外我们可以采用主从架构优化我们的读写策略。

如果读和写的业务量都很大,并且它们都在同一个数据库服务器中进行操作,那么数据库的性能就会出现瓶颈,这时为了提升系统的性能,优化用户体验,我们可以采用读写分离的方式降低主数据库的负载,比如用主数据库(master)完成写操作,用从数据库(slave)完成读操作。

除此以外,我们还可以对数据库分库分表。当数据量级达到亿级以上时,有时候我们需要把一个数据库切成多份,放到不同的数据库服务器上,减少对单一数据库服务器的访问压力。如果你使用的是 MySQL,就可以使用 MySQL 自带的分区表功能,当然你也可以考虑自己做垂直切分和水平切分。

什么情况下做垂直切分,什么情况下做水平切分呢?

如果数据库中的数据表过多,可以采用垂直分库的方式,将关联的数据表部署在一个数据库上。
如果数据表中的列过多,可以采用垂直分表的方式,将数据表分拆成多张,把经常一起使用的列放到同一张表里。
如果数据表中的数据达到了亿级以上,可以考虑水平切分,将大的数据表分拆成不同的子表,每张表保持相同的表结构。比如你可以按照年份来划分,把不同年份的数据放到不同的数据表中。2017 年、2018 年和 2019 年的数据就可以分别放到三张数据表中。
总的来说,采用垂直分表的形式,就是将一张数据表分拆成多张表,采用水平拆分的方式,就是将单张数据量大的表按照某个属性维度分成不同的小表。但需要注意的是,分拆在提升数据库性能的同时,也会增加维护和使用成本。

我们该如何思考和分析数据库调优这件事?

做任何事情之前,我们都需要确认目标。在数据库调优中,我们的目标就是响应时间更快,吞吐量更大。利用宏观的监控工具和微观的日志分析可以帮我们快速找到调优的思路和方式。

选择比努力更重要。
在进行 SQL 调优之前,可以先选择 DBMS 和数据表的设计方式。你能看到,不同的 DBMS 直接决定了后面的操作方式,数据表的设计方式也直接影响了后续的 SQL 查询语句。
SQL 查询优化分成两个部分,逻辑查询优化和物理查询优化。
虽然 SQL 查询优化的技术有很多,但是大方向上完全可以分成逻辑查询优化和物理查询优化两大块。逻辑查询优化就是通过 SQL 等价变换提升查询效率,直白一点就是说,换一种查询写法执行效率可能更高。物理查询优化则是通过索引和表连接方式等技术来进行优化,这里重点需要掌握索引的使用。
通过外援来增强数据库的性能
单一的数据库总会遇到各种限制,不如取长补短,利用外援的方式。另外通过对数据库进行垂直或者水平切分,突破单一数据库或数据表的访问限制,提升查询的性能。

总结

在这里插入图片描述

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

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

相关文章

Stable Diffusion ———LDM、SD 1.0, 1.5, 2.0、SDXL、SDXL-Turbo等版本之间关系现原理详解

前言 2021年5月,OpenAI发表了《扩散模型超越GANs》的文章,标志着扩散模型(Diffusion Models,DM)在图像生成领域开始超越传统的GAN模型,进一步推动了DM的应用。 然而,早期的DM直接作用于像素空…

cmd模式下启动mysql

1.打开cmd输入services.msc,找到MYSQL,右击属性,找到可执行文件路径,加载到环境变量。 2.打开cmd,启动MYSQL:输入net start mysql; 3.登陆MYSQL,需要管理权限; 输入:my…

Docker容器化解决方案

什么是Docker? Docker是一个构建在LXC之上,基于进程容器的轻量级VM解决方案,实现了一种应用程序级别的资源隔离及配额。Docker起源于PaaS提供商dotCloud 基于go语言开发,遵从Apache2.0开源协议。 Docker 自开源后受到广泛的关注和…

数据链路层----滑动窗口协议的相关计算

目录 1.窗口大小的相关计算 •停等协议: •后退N帧协议: •选择重传协议: 2.信道利用率相关计算 •停等协议的信道利用率: •连续ARQ(后退N帧协议,选择重传协议)的信道利用率:…

工具函数模板题(蓝桥杯 C++ 代码 注解)

目录 一、Vector容器: 二、Queue队列 三、Map映射 四、题目(快递分拣 vector): 代码: 五、题目(CLZ银行问题 queue): 代码: 六、题目(费里的语言 map&…

每日学习总结20240301

20240301 1. strchr VS strrchr strchr和strrchr是C语言标准库中的字符串处理函数,用于在字符串中查找特定字符的位置。 1.1 strchr函数 strchr函数用于在字符串中查找第一次出现指定字符的位置,并返回该位置的指针。函数原型如下: char…

你都了解2024程序员拿捏高薪的新方式吗?

2024年,程序员该如何拿高薪呢? 道理是这么讲,那我们到底应该如何去践行呢?以我自身的经验来看,网络接单无疑是我们程序员来钱最快的方式,既可以做到兼顾本职工作和快点搞钱,又可以充分利用好每一…

信息安全系列04-安全启动介绍

本文框架 1. 基本概念1.1 基本概念回顾1.2 数字签名及验签流程 2. 安全启动实施2.1 信任根选择2.1.1 使用HSM作为信任根2.1.2 使用最底层Bootloader作为信任根 2.2 校验方法确认2.2.1 基于非对称加密算法(数字签名)2.2.2 基于对称加密算法 2.3 安全启动方…

llvm AST consumer 示例

示例源码 Makefile LLVM_CONFIG ? llvm-config #CXX : clang ifndef VERBOSE QUIET : endifSRC_DIR ? $(PWD) LDFLAGS $(shell $(LLVM_CONFIG) --ldflags) COMMON_FLAGS -Wall -Wextra CXXFLAGS $(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cxxflags) LCXX :$(shell $(L…

前端面试题 ===> 【JavaScript - 高级】

公众号:需要以下pdf,关注下方 2023已经过完了,让我们来把今年的面试题统计号,来备战今年的金三银四!所以,不管你是社招还是校招,下面这份前端面试工程师高频面试题,请收好。 JavaScr…

Kubernetes基础(二十七)-nodePort/targetPort/port/containerPort/hostPort

1 nodePort/targetPort/port/containerPort 1.1 实现层级 1.2 配置方式 ########service########### apiVersion: v1 kind: Service metadata: labels: name: app1 name: app1 namespace: default spec: type: NodePort ports: - <strong>port: 8080 t…

基于C#开发OPC DA客户端——搭建KEPServerEX服务

简介 OPC DA (OLE for Process Control Data Access) 是一种工业自动化领域中的通信协议标准&#xff0c;它定义了应用程序如何访问由OPC服务器提供的过程控制数据。OPC DA标准允许软件应用程序&#xff08;客户端&#xff09;从OPC服务器读取实时数据或向服务器写入数据&…

python:pyecharts 画基金净值 月K线图

pip install pyecharts1.9.1 pyecharts-1.9.1-py3-none-any.whl 我想在本地&#xff08;PC) 画出 基金净值 月K线图&#xff0c;不想每次看图都需联网。 cd my_dir mkdir echarts cd echarts curl -O https://assets.pyecharts.org/assets/echarts.min.js 修改一下开源代码 …

记录前端面试的一些笔试题(持续更新......)

文章目录 js相关数组去重数组对象去重 实现数组unshift数组扁平化tree型数据扁平化list数据转tree型数据 对象深拷贝防抖/节流函数柯里化函数管道 随便记录一些&#xff0c;面试或者工作中都会用到&#xff0c;实现的方法很多&#xff0c;这里只是一小部分&#xff0c;有更好的…

Kubernetes(k8s第四部分之servers)

1&#xff0c;为什么不使用round-robin DNS&#xff1f; 因为DNS有缓存&#xff0c;不会清理&#xff0c;无法负载均衡 ipvs代理模式&#xff0c;这种模式&#xff0c;kube-proxy会监视Kubernetes Service 对象和Endpoints&#xff0c;调用netlink接口以相应地创建ipvs规则并…

鸿蒙学习-数据持久化

应用数据持久化概述 应用数据持久化&#xff0c;是指应用将内存中的数据通过文件或数据库的形式保存到设备上。内存中的数据形态通常是任意的数据结构或数据对象&#xff0c;存储介质上的数据形态可能是文本、数据库、二进制文件等。 HarmonyOS标准系统支持典型的存储数据形态…

win11下安装mysql

一、下载MySQL 官方下载传送门 我安装的版本是5.7.83 二、安装MySQL 1.双击安装包 2.选择Custom(自定义安装)&#xff0c;然后Next> 3.根据你的系统做选择&#xff0c;我的是64位&#xff0c;所选MySQL Servers 5.7.38 -x64&#xff0c;然后按箭头将选中的版本移到右边…

Java基于springboot的社区团购系统设计论文

摘 要 本课题是根据用户的需要以及网络的优势建立的一个社区团购系统&#xff0c;来满足用户团购的需求。 本社区团购系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于Spring Boot框架开发。在网站的整个开发过程中&#xff0c;首先对系统进行了需求分析&…

小迪安全32WEB 攻防-通用漏洞文件上传二次渲染.htaccess变异免杀

#知识点&#xff1a; 1、文件上传-二次渲染 2、文件上传-简单免杀变异 3、文件上传-.htaccess 妙用 4、文件上传-PHP 语言特性 #详细点&#xff1a; 1、检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c…

青蛙过河。

&#xff01;&#xff01;&#xff01;思路和代码源自蓝桥云课大佬题解 问题描述 小青蛙住在一条河边&#xff0c;它想到河对岸的学校去学习。小青蛙打算经过河里的石头跳到对岸。 河里的石头排成了一条直线小青蛙每次跳跃必须落在一块石头或者岸上。 不过,每块石头有一个高度,…