大型系统中的 MySQL 部署与优化(一)

一、MySQL 部署前奏

(一)部署前的考量因素简述

在大型系统中,选择 MySQL 作为数据库管理系统通常有诸多原因。首先,MySQL 是开源免费的,这意味着企业无需支付高昂的软件授权费用就能使用,对于成本控制较为严格的大型项目来说极具吸引力。其次,它具备高性能,独特的存储引擎架构使其拥有快速处理大量数据的能力,无论是读操作还是写操作,都能在高负载情况下表现出色,可有效应对大型系统中频繁的数据交互需求。再者,MySQL 有着可靠性和易用性的特点,有着严格的数据安全体系,保障数据在存储和传输过程中的安全,并且易于操作,能在各类常见操作系统上顺利运行,同时还有丰富的图形化管理工具方便进行管理维护。另外,其活跃的社区也是一大优势,庞大的开发者群体不断对其改进优化,提供了丰富的学习资源和问题解答途径,便于遇到问题时能及时找到解决方案。而且,MySQL 支持多种存储引擎,像 InnoDB、MyISAM、Memory 等,使用者可根据实际业务场景对存储引擎灵活选择,例如高并发、高可靠性需求场景可选择 InnoDB,低并发、读写分离场景可考虑 MyISAM 等。

而在部署 MySQL 之前,需要综合考量多个关键因素。一是系统环境,要明确部署的操作系统类型及版本,比如是 Linux、Windows 还是其他系统,不同操作系统对于 MySQL 的兼容性和配置方式有所差异。像 Linux 系统下可能需要关注不同发行版的特性来进行相应配置,而 Windows 系统则要考虑系统位数等情况。二是硬件资源,这包括 CPU 的性能、内存大小以及存储容量等,大型系统往往数据量庞大且并发访问量高,所以需要足够强劲的 CPU 来处理复杂的查询和运算任务,充足的内存保障数据的快速读写和缓存,大容量的存储设备来存放海量的数据。三是业务需求,要清楚系统主要的业务操作是偏向大量的读操作、写操作还是读写均衡,对数据一致性、事务处理的要求如何等,根据这些来确定后续合适的配置和优化方向。例如电商系统在促销活动期间会面临极高的并发写操作压力,就需要针对性地提前做好相关部署规划。

(二)软件版本选择简述

选择合适的 MySQL 版本对于大型系统的稳定高效运行至关重要,这需要从系统兼容性、功能需求等多方面来综合考量。

从系统兼容性角度来看,不同版本的 MySQL 对操作系统、硬件环境等有着不同的适配情况。例如,官方推荐在一些较新的操作系统上可使用更高版本的 MySQL 以充分发挥其性能优势,像在 CentOS 7 及以上版本中,MySQL 8.0 已经针对其进行了优化,运行起来更加稳定且能展现出良好的性能表现;而对于某些老旧的操作系统版本,可能只能选择与之兼容的旧版 MySQL 来确保能够正常安装和使用。

在功能需求方面,各个版本的 MySQL 有着不同的特点和优势。像 MySQL 5.6 版本,于 2013 年发布,带来了 InnoDB 存储引擎优化,支持全文索引,复制功能增强,支持 GTID(全局事务 ID)从而改进了主从复制,同时在性能上也优化了查询优化器,适用于当时的中小型业务,不过如今相对来说已较为过时。MySQL 5.7 版本发布于 2015 年,增加了 JSON 数据类型和相关函数,支持虚拟列和生成列从而改进查询性能,复制方面改进了并行复制,安全性也有所提升,默认支持 SSL 和密码强度策略,这一版本适用于大部分应用场景,至今仍被广泛使用。而 MySQL 8.0 版本在 2018 年推出,有着诸多重要改进,其默认字符集改为 UTF-8(utf8mb4),能更好地支持多语言,开始支持窗口函数和公共表表达式(CTE),JSON 功能进一步增强,添加了更多 JSON 函数,采用 redo log 刷新机制提升崩溃恢复性能,在性能上优化了索引管理(如不可见索引)并支持 Hash Join,安全性方面增强了密码管理和权限系统,更适合现代化业务系统,特别是那些需要复杂查询和多语言支持的场景。

此外,对于有特殊功能需求的情况也要着重考虑版本选择。例如,如果业务中大量涉及 JSON 数据的操作且需要较为复杂的 JSON 函数支持,那 MySQL 8.0 版本会是更好的选择;要是对安全性要求极高,需要如数据加密、审计日志等高级安全功能,那么付费的 MySQL 企业版则可以满足需求,它提供了完整功能以及官方的技术支持,不过对于成本敏感的项目来说,免费开源的社区版可能更合适,虽然社区版缺少部分高级功能,但基本能满足常规的使用场景。 总之,只有全面权衡系统兼容性和功能需求等因素,才能挑选出最契合大型系统部署的 MySQL 版本。

二、MySQL 部署步骤

(一)服务器端安装

1. 安装包获取简述

要获取 MySQL 服务器端安装包,最常用且可靠的方式是从官方渠道下载。我们可以通过浏览器输入官网网址 www.mysql.com 打开官网页面,找到 “DOWNLOADS” 选项并点击进入下载页面,接着下滑至页面下方,点击 “MySQL Community (GPL) Downloads »”,再点击 “MySQL Community Server”。这里会展示最新版的 MySQL,若想安装以前的版本,则点击下方红色箭头所指位置。

在选择具体版本进行下载时,建议依据系统环境以及项目需求来定,如果没有特殊关联,可选择最新的稳定版,但要注意不能选开发版本(也就是所谓的实验版)。同时,电脑一般都是 64 位的,通常不要下载 32 位的版本(不清楚电脑型号的话,右键点击 “此电脑”,选择 “属性” 即可看到系统类型是多少位操作系统)。选择好合适的版本后,点击对应的下载按钮,若点击下载弹出让注册登录下载的页面,可以不用理会,直接点击 “No thanks,just start my download.” 就能开始下载了。另外,下载完成解压后,要记清文件保存路径,方便后续安装操作,且安装包最好不要置于 C 盘,以免后续可能出现一些权限等相关问题。

2. 安装流程详解

以 Windows 环境为例,在下载好 MySQL 服务器端安装包后,双击安装包文件,即可开始安装流程。

首先,会出现安装向导界面,有 3 种安装方式可供选择,分别是 “Typical(典型安装)”、“Complete(完全安装)” 和 “Custom(定制安装)”,对于大多数用户而言,选择 “Typical” 就可以满足基本需求,单击 【Next】 按钮进入下一步。

接着进入正式安装界面,确认相关信息后单击 【Install】 按钮开始安装,这个过程需要耐心等待一段时间,直至安装完成,然后在弹出的窗口中单击 【Next】 按钮完成基础安装步骤。

安装完毕后,通常会有配置向导的选项,比如选择 “Configure the MySQL server now” 复选框(不同版本安装包可能具体表述略有差异),单击 【Finish】 按钮进入配置向导,单击 【Next】 按钮进入选择配置类型对话框,这里配置类型有 2 种:“Detailed Configuration(详细配置)” 和 “Standard Configuration(标准配置)”。标准配置选项适合想要快速启动 MySQL 而不必考虑服务器配置的新用户;详细配置选项适合想要更加细粒度控制服务器配置的高级用户,可按需进行选择,此处假设我们选择 “Detailed Configuration” 选项并点击 【Next】 按钮继续配置流程。

下一步是进行服务器类型选择,分为 “Developer Machine(开发机器)”、“Server Machine(服务器)” 和 “Dedicated MySQL Server Machine(专用 MySQL 服务器)”3 种,可根据实际使用场景来决定,例如个人学习研究用,一般可选择 “Developer Machine” 选项,再点击 【Next】 按钮。

之后进入数据库使用情况对话框,有 “Multifunctional Database(多功能数据库)”,“Transactional Database Only(只是事务处理数据库)”,“Non-Transactional Database Only(只是非事务处理数据库)” 这 3 个选项,其中多功能数据库对 InnoDB 和 MyISAM 表都适用,通常可选择 “Multifunctional Database” 选项,随后点击 【Next】 按钮。

再进入 InnoDB 表空间对话框,一般默认位置是 MySQL 服务器数据目录,这里若无特殊需求可不做修改,继续点击 【Next】 按钮进入并发连接选择对话框,有 “Decision Support (DSS)/OLAP(决策支持)”(如果服务器不需要大量的并行连接可以选择该选项)、“Online Transaction Processing(OLTP,联机事务处理)”(如果服务器需要大量的并行连接则选择该选项)、“Manual Setting(人工设置)”(选择该选项可以手动设置服务器并行连接的最大数目)这些选项,根据服务器预计的并发连接情况来选择,例如预计并发连接量不大时可选择 “Decision Support (DSS)/OLAP” 选项,点击 【Next】 按钮。

进入联网选项对话框,默认情况是启用 TCP/IP 网络,默认端口为 3306,正常情况下这里也可不做修改,继续点击 【Next】 按钮进入字符集选择对话框,若有特定语言支持需求等情况,可以对默认设置做修改,比如选中 “Manual Selected Default Character Set/Collation” 选项,在 “Character Set” 选框中将默认的字符集(如 latin1)修改为自己需要的(像 gb2312 等能更好支持中文等情况),然后单击 【Next】 按钮进入服务选项对话框,服务名一般默认为 “MySQL”,这里通常也不用修改,点击 【Next】 按钮进入安全选项对话框,这一步很关键,需要在密码输入框中输入 root 用户的密码(密码设置要遵循一定的强度规则,在实际应用时密码不可过于简单,且一定要牢记设置的密码),同时要谨慎考虑是否创建匿名用户账户,出于安全原因,一般不建议选择创建匿名用户账户选项,设置完毕后,最后一步是提交配置,单击 【Execute】 按钮即可完成服务器端的安装与基础配置流程。

另外,在 Linux 系统下安装,以 CentOS 系统为例,一种常见方式是通过 yum 在线安装。先下载 mysql 的 rpm 包安装到 yum 仓库里,比如服务器的系统是 centOS 7.3 时,可选择对应的 linux 版本链接地址,使用命令 wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm(若提示 wget:未找到命令就先安装 wget:yum -y install wget,然后再执行上述下载命令),接着通过 yum 仓库安装 mysql 源,命令为 yum -y localinstall mysql80-community-release-el7-3.noarch.rpm,之后使用 yum -y install mysql-community-server 命令进行 mysql 的安装,安装完成后使用 systemctl start mysqld 命令启动 mysql 服务,还可以使用 systemctl enable mysqld 命令设置开机启动以及 systemctl daemon-reload 命令让设置生效等后续操作,后续也涉及到如修改 root 用户密码等配置步骤,与 Windows 环境下有一些不同之处,需根据实际操作情况来进行相应配置调整。

3. 常见问题解决

在服务器端安装 MySQL 时,可能会遇到各种各样的问题,以下是一些常见问题及对应的解决方案:

  • 安装包无法下载问题
    • 若点击下载按钮后没有反应或者提示网络错误等,首先检查网络连接是否正常,可尝试切换网络环境(如从 Wi-Fi 切换到有线网络或者反之),或者尝试使用不同的浏览器重新访问官网下载页面进行下载操作。
    • 若遇到需要注册登录才能下载的情况,按照前文所述,直接点击 “No thanks,just start my download.” 按钮尝试跳过注册登录直接下载,若此方法无效,可查看官网是否有相关说明或者咨询官方客服了解具体原因及解决办法。
  • 安装过程中出现未响应情况
    • 可能是电脑当前系统资源紧张导致,关闭一些正在运行的其他大型软件或者不必要的后台程序,释放内存和 CPU 资源后,再次尝试安装操作,看是否能够恢复正常安装流程。
    • 安装包可能存在损坏问题,重新从官网下载安装包,确保下载过程完整无中断且文件大小与官网标注一致后,再次进行安装尝试。
  • 配置环节报错问题
    • 例如在配置服务器参数时提示某个参数设置错误,仔细检查对应参数的填写要求和格式规范,对照官方文档或者相关教程进行正确的参数修改,比如字符集设置不符合要求、端口号被占用等情况,都需要针对性地去调整参数或者解决冲突(如端口被占用可更换其他未使用的端口号)。
    • 若遇到类似 “The service already exists.” 的提示,表明之前已经安装过 mysql,并且没有删除干净,此时需要以管理员身份运行命令提示符(CMD),输入 sc query mysql 查看一下名为 mysql 的服务,若确实存在,接着输入 sc delete mysql 删除 MySQL 服务后,再继续进行安装配置操作就能成功了。
  • 启动服务失败问题
    • 使用 net start mysql 命令开启 mysql 的服务失败时,可能是服务器无法连接启动,这时可以手动启动,在系统搜索栏搜索 “服务” 打开后,找到 MySQL 服务器界面手动启动或者关闭就行了。另外,在 Linux 系统下若启动失败,可查看相关的日志文件(如 CentOS 系统下可查看 /var/log/mysqld.log 文件),从中查找可能的错误原因,比如依赖的软件包未安装完整等情况,根据提示安装缺失的依赖后再次尝试启动服务。
    • 安装完 mysql 后,若首次启动服务提示密码相关问题,像在一些版本中会自动生成一个临时密码记录在日志文件里(如 CentOS 系统下的 /var/log/mysqld.log 文件),可先查看并复制这个临时密码,注意密码可能带有特殊字符,复制时要确保准确,然后通过命令 mysql -u root -p 粘贴刚刚复制的临时密码进入 mysql 环境,按照相应版本要求及时修改 root 用户的密码(不同版本对密码强度等有不同要求,如 mysql5.7 之后的密码策略默认必须大小写英文字母和数字加特殊字符混合),修改成功后再尝试启动服务。

(二)客户端工具安装

1. 客户端工具选型简述

市面上有多款常用的 MySQL 客户端工具,各有特点及适用场景,下面为大家介绍几款常见的工具:

  • Navicat:它是一款功能强大的桌面版 MySQL 数据库管理和开发工具,界面和微软 SQL Server 的管理器很像,易学易用,支持中文,提供了强大的图形用户界面,涵盖数据导入导出、数据同步、数据库设计等多种功能,适合开发者和数据库管理员进行全面的数据库管理操作,但它是付费软件,不过有免费版本提供(功能上会有一定限制)。
  • SQLyog:由 Webyog 公司出品的一款简洁高效、功能强大的图形化 MySQL 数据库管理工具,特别适合在 Windows 平台使用,能够快速直观地让用户从世界的任何角落通过网络来维护远端的 MySQL 数据库,具有方便快捷的数据库同步与数据库结构同步工具、易用的数据库、数据表备份与还原功能以及支持导入与导出多种格式的数据等优点,同样有付费版本,也提供免费试用版供用户在购买许可证之前进行测试体验。
  • MySQL Workbench:这是 MySQL 官方提供的图形化管理工具,功能很强大,是一个统一的可视化开发和管理平台,该平台提供了许多高级工具,可支持数据库建模和设计、查询开发和测试、服务器配置和监视、用户和安全管理、备份和恢复自动化、审计数据检查以及向导驱动的数据库迁移等功能,适用于数据库开发和管理全流程操作,并且完全开源免费,可在 Windows,Linux 和 Mac 等多种操作系统上使用。
  • phpMyAdmin:是最常用的 MySQL 维护工具之一,它是一个用 PHP 开发的基于 Web 方式架构在网站主机上的 MySQL 管理工具,支持中文,方便在网页端对数据库进行管理,优势在于操作相对简单,部署后通过浏览器就能访问管理数据库,但对于大数据库的备份和恢复不太方便,比较适合对数据库操作需求不是特别复杂且希望通过网页便捷管理的场景。
  • DBeaver:一款免费和开源的通用数据库管理工具和 SQL 客户端,支持多种关系型数据库,包括 MySQL、PostgreSQL、Oracle 等众多常见数据库,功能也比较强大,其特点是完全开源免费,在国内使用热度较高,不过安装包相对有点大,适合需要同时管理多种不同类型数据库且追求开源免费工具的用户选择。

大家可以根据自己的操作系统平台、具体业务需求(是侧重简单的数据查询操作还是复杂的数据库设计开发等)以及是否愿意付费购买软件等因素综合考虑,来选择适合自己的 MySQL 客户端工具。

2. 具体安装过程

以 SQLyog 客户端工具在 Windows 系统下的安装为例,介绍具体安装步骤:

首先,下载 SQLyog 安装包,可以从官网(https://webyog.com/product/sqlyog/trial/ )下载或者使用官方推荐的其他可靠渠道获取安装包。

下载完成后,双击安装包启动安装程序,会弹出语言选择界面,选择中文简体语言,点击 “OK”;之后,点击 “下一步”;接着,会出现软件使用条款界面,勾选接受条款后,点击 “下一步”;随后进入选择要安装的功能界面,可根据自身需求选择需要安装的功能组件(一般默认全选即可满足基本使用需求),再点击 “下一步”;然后是选择安装位置界面,可自行指定安装目录,建议选择非系统盘且路径比较清晰好找的位置,设置好后点击 “下一步”;安装程序会开始进行文件复制等安装操作,等待安装完成后,提示安装完成,点击 “下一步”;最后点击 “完成”,即可运行 SQLyog 软件。首次运行时,可能需要输入名称和证书等进行注册,若出现 “感谢您注册” 字样,说明注册成功了,之后就能正常使用该客户端工具了。

再比如 MySQL Workbench 在 Windows 系统下安装,从官网(https://dev.mysql.com/downloads/workbench/ )下载对应版本的安装包后,双击安装包启动安装向导,在安装向导中,先是选择安装语言等基础设置,一般选择默认语言(通常有英语等多种语言可选,根据自己熟悉的语言选择即可),点击 “Next”;接着会展示软件许可协议,阅读并勾选接受协议后点击 “Next”;之后选择安装路径,可以自行修改默认路径或者使用默认的安装路径,点击 “Next”;然后会显示安装进度条,等待安装完成后点击 “Finish” 即可完成安装操作,安装完成后就能在开始菜单或者桌面上找到对应的快捷方式启动该客户端工具了。

不同客户端工具安装步骤会有一定差异,但大致都是按照选择语言、接受协议、设置安装路径等环节来进行,具体操作时按照安装界面提示逐步完成即可。

3. 客户端配置与连接

以 SQLyog 客户端工具为例,在安装完成后,需要配置数据库连接信息才能连接到 MySQL 服务器进行操作。

打开 SQLyog 软件,点击 “新建” 按钮,输入连接名称(可自行定义一个便于识别的名称,比如 “local-mysql” 代表本地的 MySQL 连接等),之后,输入 MySQL 服务器用户账号信息(根据实际安装配置 MySQL 服务器时设置的用户名和密码填写,这里通常用户名是 “root”,密码就是安装服务器时设定的密码);接着,点击 “测试连接” 按钮,如果连接成功,会出现弹窗提示 “Connection successful!”;之后,点击 “保存” 按钮,保存刚才配置成功的数据库连接信息。之后每次打开 SQLyog,选择对应的连接名称,点击 “连接” 按钮,就能连接到相应的 MySQL 服务器进行数据库管理操作了,比如进行数据查询、修改等操作。

对于命令行客户端工具(如 mysql 官方自带的命令行工具),在连接 MySQL 服务器时,可通过命令 mysql [-h 127.0.0.1] [-P 3306] -u root -p 来操作,其中参数 -h 用于指定 MySQL 服务所在的主机 IP(如果连接本地的 MySQL,可不加此参数,默认就是本地 127.0.0.1),-P 用于指定 MySQL 服务端口号(默认是 3306,如果安装时修改了端口号则填写实际的端口号),-u 用于指定 MySQL 数据库用户名(一般是 root),-p 表示需要输入对应的密码,在命令行输入此命令后回车,会提示输入密码,输入正确密码后就能连接到 MySQL 服务器,进入命令行交互界面,可以执行各类 SQL 语句来操作数据库了。

另外,在配置连接时,如果遇到连接不上的情况,需要检查多个方面:一是检查客户端填写的服务器 IP、端口号、用户名和密码是否准确无误;二是查看服务器端是否开启了相应的端口访问权限(比如在服务器的防火墙设置中是否允许外部通过对应的端口访问 MySQL 服务,像在 Linux 系统下可使用命令 firewall-cmd --zone=public --add-port=3306/tcp —permanent 命令开启 3306 端口访问权限,并通过 firewall-cmd —reload 命令让设置生效,然后使用 firewall-cmd —query-port=3306/tcp 命令查询端口是否已开启,显示 “yes” 则表示开启成功);三是查看 MySQL 服务器本身是否正常启动运行,可通过相应操作系统下查看服务状态的方式(如 Windows 系统下在服务管理中查看 MySQL 服务状态,Linux 系统下使用相关命令查看进程等方式)来确认,若服务器未正常启动,则需要排查服务器端启动失败的原因并解决后,再尝试客户端连接操作。

三、MySQL 优化策略

(一)索引优化

1. 索引类型及适用场景简述

在 MySQL 中,常见的索引类型有 B-Tree 索引、哈希索引等,它们各有特点,适用于不同的查询场景。

B-Tree 索引是最常见的索引类型,通常说的索引指的就是 B 树索引,使用的是 B + 树的结构来存储数据。在 B + 树中每一个叶子节点都包含一个指向下一个节点的叶子指针,可以方便地进行叶子节点之间的遍历。它能够加快存储引擎的查找速度,通常情况下,索引的大小远远小于表中数据的大小,使用了 B 树索引之后就不用再进行全表扫描,而是从索引的根节点开始搜索,根节点中存放了指向下一个节点的指针,存储引擎根据这些指针向下一层进行查找,通过比较节点中的值,就能得到合适的节点。其指针中定义了子节点中的上限和下限,最终存储引擎能够判断节点中的值是否存在。

B-Tree 索引非常适合数据重复度低的字段,例如身份证号码、手机号码、QQ 号等字段,常用于主键、唯一约束,一般在在线交易的项目中用到的较多。它的优点在于当没有索引的时候,执行类似 “where qq=40354446” 这样的条件查询,在数据量很大时会非常耗时,而有了 B-tree 索引就像翻书目录一样,可直接定位 rowid 立刻找到想要的数据,实质减少了 I/O 操作从而提高速度,并且它有一个显著特点即查询性能与表中数据量无关。不过,B-Tree 索引不适合键值重复率较高的字段。

哈希索引则是基于哈希表实现的索引,它能以非常快的速度进行等值查询,也就是查找特定值的效率极高。通常适用于一些需要快速查找单个值的场景,例如在缓存系统或者一些键值对形式的数据查找中比较适用。但哈希索引也有局限性,它不支持范围查询,比如无法方便地查找某个区间内的值;也不支持排序操作,因为哈希表本身是无序的;而且对于键值重复较多的数据,可能在查询时需要遍历多个哈希桶,性能会有所下降。

不同的存储引擎对这些索引的支持和使用方式也略有差异,比如 InnoDB 使用 B+tree 存储引擎以不同的方式使用 BTree 索引,MyISAM 使用前缀压缩技术使得索引更小(但也可能导致连接表查询性能降低),而 MyISAM 索引通过数据的物理位置来引用被索引的行,InnoDB 则根据主键来引用被索引的行。了解这些索引类型及其适用场景,能帮助我们在实际应用中更好地根据业务需求进行选择,发挥索引提升查询性能的作用。

2. 索引创建原则

创建索引是提升 MySQL 查询性能的重要手段,但需要遵循一定的原则,才能达到理想效果且避免对性能产生负面影响。

首先,优先选择唯一性索引。唯一性索引的值是唯一的,可以更快速地通过该索引来确定某条记录。例如学生表中学号是具有唯一性的字段,为该字段建立唯一性索引能很快确定某个学生的信息。而像姓名这类可能存在同名现象的字段,如果用其建立索引,反而可能降低查询速度。

其次,为经常需要排序、分组和联合操作的字段建立索引。经常需要 ORDER BY、GROUP BY、DISTINCT 和 UNION 等操作的字段,排序操作会耗费较多时间,如果为其建立索引,就可以有效地避免排序操作带来的性能损耗,提高查询效率。

再者,对于常作为查询条件的字段建立索引。如果某个字段经常用来做查询条件,那么该字段的查询速度会影响整个表的查询速度,为这样的字段建立索引,可以显著提高整个表的查询速度。

同时,要限制索引的数目。每个索引都需要占用磁盘空间,索引越多,占用的磁盘空间就越大,而且在修改表时,对索引的重构和更新会很麻烦,过多的索引还会使更新表变得非常耗时,所以并非索引越多越好。

另外,尽量使用数据量少的索引。如果索引的值很长,那么查询的速度会受到影响,例如对一个 CHAR (100) 类型的字段进行全文检索需要的时间肯定要比对 CHAR (10) 类型的字段进行检索花费的时间更多。对于较长的索引字段,最好使用值的前缀来索引,比如 TEXT 和 BLOG 类型的字段,进行全文检索会比较浪费时间,这时若只检索字段前面的若干个字符来创建前缀索引,就可以提高检索速度。

还要遵循最左前缀匹配原则,这是非常重要的一点。MySQL 会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如 “a = 1 and b = 2 and c> 3 and d = 4”,如果建立 (a,b,c,d) 顺序的索引,d 是用不到索引的;如果建立 (a,b,d,c) 的索引则都可以用到,a、b、d 的顺序可以任意调整。并且 “=” 和 “in” 可以乱序使用,比如 “a = 1 and b = 2 and c = 3” 建立 (a,b,c) 索引可以任意顺序,MySQL 的查询优化器会帮你优化成索引可以识别的形式。

此外,尽量选择区分度高的列作为索引,区分度的公式是 count (distinct col)/count (*),表示字段不重复的比例,比例越大扫描的记录数越少,唯一键的区分度是 1,而一些状态、性别字段可能在大数据面前区分度就是 0。一般对于需要 join 的字段,要求区分度在 0.1 以上,即平均 1 条记录扫描不超过 10 条记录为宜。

最后,索引列不能参与计算,要保持列 “干净”。比如 “from_unixtime (create_time) = ’2014-05-29’” 就不能使用到索引,原因是 B + 树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,成本太大,所以语句应该写成 “create_time = unix_timestamp (’2014-05-29’)”。并且要尽量的扩展索引,不要新建索引,比如表中已经有 a 的索引,现在要加 (a,b) 的索引,那么只需要修改原来的索引即可。

总之,选择索引的最终目的是为了使查询的速度变快,在实际应用中要综合多方面因素,根据具体的业务场景进行分析和判断,选择最合适的索引方式。

3. 索引优化案例分析

以下通过一个实际案例来展示索引优化前后对查询性能的提升效果,帮助大家更好地理解索引优化的重要性。

假设我们有一个电商系统中的订单表 “orders”,包含字段 “order_id”(订单编号,主键)、“customer_id”(客户编号)、“order_date”(下单日期)、“total_amount”(订单总金额)等,数据量达到了数十万条。

最初,我们经常会执行这样一个查询语句,用于查找某个特定客户在某个时间段内的订单信息:“SELECT * FROM orders WHERE customer_id = 123 AND order_date BETWEEN '2023-01-01' AND '2023-06-30'”。在没有对 “customer_id” 和 “order_date” 字段建立合适索引的情况下,数据库会进行全表扫描来查找满足条件的数据,查询耗时可能达到数秒甚至更长时间,严重影响系统的响应速度,尤其在高并发的业务场景下,这种性能表现是难以接受的。

接下来,我们根据索引创建原则,为 “customer_id” 和 “order_date” 字段建立联合索引(因为经常一起作为查询条件),使用语句 “CREATE INDEX idx_customer_order ON orders (customer_id, order_date)”。

建立索引后再次执行上述查询语句,数据库就可以利用索引快速定位到满足 “customer_id = 123” 条件的索引节点,然后在这个基础上进一步筛选出 “order_date” 在指定区间内的数据,大大减少了需要扫描的数据量,查询耗时可能降低到几十毫秒甚至更短,性能提升非常显著,极大地改善了系统的响应性能,使得用户在查询订单信息时能快速得到结果,提升了用户体验。

通过这个案例可以看出,合理地创建索引对于提升查询性能有着至关重要的作用,不过也要注意避免过度创建索引,以免带来不必要的磁盘空间占用和更新操作的性能损耗等问题。

(二)查询优化

1. 编写高效查询语句简述

编写高效的查询语句是优化 MySQL 性能的关键环节之一,以下是一些实用的技巧。

首先,要合理使用索引。在经常进行连接,但没有指定为外键的列上建立索引,对于频繁进行排序或分组(即进行 group by 或 order by 操作)的列也应建立索引,同时在条件表达式中经常用到的不同值较多的列上建立检索,而不同值少的列(比如只有 “男”“女” 两个值的 “性别” 列)上则无需建立索引,因为建立了也可能不会提高查询效率,反而会严重降低更新速度。若待排序的列有多个,可以建立复合索引。并且当数据库表更新大量数据后,删除并重建索引有时可以提高查询速度。

其次,避免或简化排序操作。应当简化或避免对大型表进行重复的排序,比如要确保索引中包含所有待排序的列,且 group by 或 order by 子句中列的次序与索引的次序尽量保持一致,排序的列如果来自不同的表也可能导致无法利用索引避免排序,这种情况下可以考虑合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,例如缩小排序的列的范围等。

再者,要消除对大型表行数据的顺序存取。在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响,避免这种情况的主要方法就是对连接的列进行索引。例如,学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)做连接时,就要在 “学号” 这个连接字段上建立索引。另外,还可以使用并集来避免顺序存取,比如对于一些会强迫优化器使用顺序存取的 where 子句,可以通过改写语句使用并集的方式来利用索引路径处理查询。

还要避免相关子查询,一个列的标签同时在主查询和 where 子句中的子查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次,查询嵌套层次越多,效率越低,所以应当尽量避免子查询,若不可避免,则要在子查询中过滤掉尽可能多的行。

此外,要慎用通配符查询,像 “LIKE” 关键字支持通配符匹配,但这种匹配特别耗费时间,尤其是左右都需要模糊匹配时(如 “SELECT * FROM customer WHERE zipcode LIKE ‘% abc%’”),会导致全表扫描,若要提高效率,可尽量不以 “%” 开始(如 “SELECT * FROM customer WHERE zipcode LIKE ‘abc%’”),或者考虑使用全文检索等方式(需注意表引擎是否支持等情况)。

同时,要减少函数在条件中的使用,比如 “SELECT id FROM t WHERE num/2 = 100”“SELECT id FROM t WHERE date (createdate) > '2016-07-01'” 这类在 where 子句中对字段进行函数、算术运算或其他表达式运算的语句,会导致引擎无法使用索引,应改为 “SELECT id FROM t WHERE num = 100 * 2”“SELECT id FROM t WHERE createdate > '2005-11-30 00:00:00'” 这样的形式。

遵循这些编写查询语句的技巧,能有效提升查询效率,减少不必要的性能损耗,让 MySQL 在处理查询任务时更加高效。

2. 利用缓存机制

MySQL 拥有缓存机制,合理利用可以显著减少磁盘 I/O 操作,提升查询性能。

MySQL 的缓存机制主要包括查询缓存和系统缓存两部分。查询缓存用于缓存查询语句的结果集,如果后续有相同的查询语句再次执行,数据库就可以直接从缓存中获取结果,而无需重新执行查询逻辑、读取磁盘数据等操作,大大节省了时间。不过,查询缓存也有一些限制,例如当对表进行更新操作时,与之相关的查询缓存会失效,所以在数据频繁更新的场景下,查询缓存的命中率可能会受到影响。

要合理设置查询缓存,需要考虑缓存的大小等参数配置。可以通过参数 “query_cache_size” 来指定查询缓存的内存大小,设置合适的值很关键,过小可能导致缓存很快被填满,无法充分发挥缓存的作用;过大则可能占用过多内存资源,影响系统整体性能。一般需要根据系统的数据量、查询频率等实际情况进行调整。

系统缓存方面,像 InnoDB 存储引擎中的内存缓存池(buffer pool)也是非常重要的缓存机制,它用于缓存表中的数据和索引等信息,将磁盘上的数据读取到内存中,以加快数据库访问速度和提高性能。参数 “innodb_buffer_pool_size” 就是用于控制 InnoDB 存储引擎的内存缓存池大小,当这个参数设置的值越大,InnoDB 存储引擎所能利用的内存空间就越大,可以缓存更多的数据及索引,从而能够减少磁盘 I/O 的次数。但同样要注意,如果缓存池过小,有可能导致频繁的磁盘 I/O,影响数据库性能;而缓存池过大,则会占用太多的系统资源,导致性能下降,需要根据业务数据规模、系统硬件配置等多方面因素,合理设置其大小,通常可以设置为总内存的 3/4 至 4/5 左右(具体还需结合实际情况微调)。

另外,对于其他一些缓冲区参数,比如 “sort_buffer_size”(用于加快 order by 和 group by 操作,连接独享,设置过大会大量消耗内存)、“read_buffer_size”(读入缓冲区大小)等,也需要根据业务场景合理配置,让系统在缓存数据、处理查询等方面达到较好的性能平衡,充分利用缓存机制来提升 MySQL 整体的查询性能。

3. 复杂查询优化案例

在处理多表连接、分组排序等复杂查询场景时,优化思路尤为重要,下面通过一个实际案例来说明。

假设有三个表,分别是 “customers” 表(包含 “customer_id”、“customer_name” 等字段)、“orders” 表(包含 “order_id”、“customer_id”、“order_date”、“total_amount” 等字段)和 “order_items” 表(包含 “item_id”、“order_id”、“product_id”、“quantity” 等字段),现在要查询每个客户的订单总金额以及对应的订单数量,并且按照订单总金额降序排列,查询语句可能最初写成这样:

“SELECT c.customer_name, SUM(oi.total_amount) AS total_amount, COUNT(o.order_id) AS order_count

FROM customers c

JOIN orders o ON c.customer_id = o.customer_id

JOIN order_items oi ON o.order_id = oi.order_id

GROUP BY c.customer_name

ORDER BY total_amount DESC;”

在未优化之前,这样的查询可能会面临性能问题,尤其是数据量较大时。

优化思路如下:

首先,对于连接字段 “customers” 表中的 “customer_id”、“orders” 表中的 “customer_id” 和 “order_id” 以及 “order_items” 表中的 “order_id”,都应该建立索引,因为多表连接时,利用索引能快速定位关联的数据,减少全表扫描和嵌套循环的次数,提高连接效率。

然后,考虑到有分组(GROUP BY)和排序(ORDER BY)操作,对于分组字段 “customer_name” 以及用于排序的计算字段 “total_amount”(这里其实可以考虑通过建立视图或者使用子查询提前计算好每个客户的总金额,避免在最终查询时重复计算,不过为了贴合这个案例场景暂不做此改动),也需要确保相关索引能覆盖这些操作,或者建立合适的复合索引来提升效率。比如可以建立复合索引 “idx_customer_total_amount”(包含 “customer_name”、“total_amount” 字段),并且根据最左前缀匹配原则来保证索引能被有效利用。

经过上述优化后,再次执行这个复杂查询,数据库就能更高效地利用索引进行连接、分组和排序操作,减少了大量的数据读取和计算量,查询性能会得到显著提升,原本可能需要几秒甚至更长时间的查询,优化后可能缩短到几百毫秒甚至更短,在实际业务场景中,尤其是面对高并发的复杂查询请求时,这样的性能提升能极大地改善系统的响应能力和用户体验。

(三)配置参数优化

1. 关键配置参数解读

在 MySQL 中,有一些关键的配置参数对数据库性能有着重要影响,下面选取几个重要的参数进行解读。

innodb_buffer_pool_size:这是 MySQL 中 InnoDB 存储引擎中的一个极为重要的参数,用于控制 InnoDB 存储引擎的内存缓存池大小。InnoDB 存储引擎将数据和索引保存在表空间中,并且支持事务和行级锁等高级特性。其中内存缓存池(buffer pool)是 InnoDB 存储引擎的最重要的内存区域,用于缓存表中的数据和索引等信息,将磁盘上的数据读取到内存中,以加快数据库访问速度和提高性能。一般来说,当 innodb_buffer_pool_size 设置的值越大,InnoDB 存储引擎所能利用的内存空间就越大,可以缓存更多的数据及索引,从而能够减少磁盘 I/O 的次数,提高数据库性能。不过,如果缓存池过小,有可能导致频繁的磁盘 I/O,从而影响数据库性能;而缓存池过大,则会占用太多的系统资源,导致性能下降。因此,在实际的应用中,需要根据业务数据规模、系统硬件配置等多方面因素,合理设置 innodb_buffer_pool_size 的大小,通常可以考虑设置为总内存的 3/4 至 4/5 左右(具体还需结合实际情况微调)。

max_connections:它代表 MySQL 的最大连接数。如果服务器的并发连接请求量较大,建议调高此值,以增加并行连接数量,但这建立在机器能支撑的情况下,因为如果连接数越多,MySQL 会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设置数值。如果数值过小,经常会出现 “ERROR 1040:Too many connections” 错误,可以通过 “mysql>show status

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

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

相关文章

量子通信学习路径(一)

量子通信是一门融合量子力学和通信技术的交叉学科&#xff0c;其核心目标是利用量子力学的特性&#xff08;如叠加态和纠缠&#xff09;实现信息传递和安全通信。以下是一个系统学习量子通信的完整大纲&#xff0c;从基础知识到实际应用逐步深入&#xff0c;帮助建立全面的知识…

QGIS修行记-如何使用QGIS进行换行标注

问题描述 QGIS根据指定的文字进行换行标注 项目的需要先描述一下&#xff1a; 需要标注的字段太长&#xff0c;需要进行换行标注需要换行的数据不确定有多少&#xff08;适用于批量数据的操作&#xff09;我需要根据指定文字进行换行 如&#xff1a;成山头海洋生态自然保护区…

指针的深入讲解

本章重点&#xff1a; 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的指针回调函数 我们在指针的初阶的时候主要讲了&#xff1a; 1.指针就是变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间 2.指针的大小是固定4个…

LWIP协议:三次握手和四次挥手、TCP/IP模型

一、三次握手&#xff1a;是客户端与服务器建立连接的方式&#xff1b; 1、客户端发送建立TCP连接的请求。seq序列号是由发送端随机生成的&#xff0c;SYN字段置为1表示需要建立TCP连接。&#xff08;SYN1&#xff0c;seqx&#xff0c;x为随机生成数值&#xff09;&#xff1b;…

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现

一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现&#xff1a; Python。 我们将用Python来实现一个学生管理应用&#xff0…

WatchAlert - 开源多数据源告警引擎

概述 在现代 IT 环境中&#xff0c;监控和告警是确保系统稳定性和可靠性的关键环节。然而&#xff0c;随着业务规模的扩大和数据源的多样化&#xff0c;传统的单一数据源告警系统已经无法满足复杂的需求。为了解决这一问题&#xff0c;我开发了一个开源的多数据源告警引擎——…

ABAP SQL 取日期+时间最新的一条数据

我们在系统对接的时候&#xff0c;外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的&#xff0c;那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案&#xff1a; 方式 1&#xff1a;SELECT MAX 可以通过两个 SELECT MAX 来取…

Vue3 + Element-Plus + vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS 父组件实现真正上传(最新保姆级)

Vue3 Element-Plus vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS&#xff08;最新保姆级&#xff09;父组件实现真正上传 1、效果展示2、UploadImage.vue 组件封装3、相关请求封装4、SwiperConfig.vue 调用组件5、后端接口 1、效果展示 如果没有安装插件&…

容器化技术全面解析:Docker 与 Containerd 的深入解读

目录 Docker 简介 1. 什么是 Docker&#xff1f; 2. Docker 的核心组件 3. Docker 的主要功能 4. Docker 的优点 5. Docker 的使用场景 Containerd 简介 1. 什么是 Containerd&#xff1f; 2. Containerd 的核心特性 3. Containerd 的架构 4. Containerd 与 Docker 的…

LNMP+discuz论坛

0.准备 文章目录 0.准备1.nginx2.mysql2.1 mysql82.2 mysql5.7 3.php4.测试php访问mysql5.部署 Discuz6.其他 yum源&#xff1a; # 没有wget&#xff0c;用这个 # curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo[rootlocalhost ~]#…

Android Studio的笔记--BusyBox相关

BusyBox 相关 BusyBoxandroid上安装busybox和使用示例一、下载二、移动三、安装和设置环境变量四、使用 busybox源码下载和查看 BusyBox BUSYBOX BUSYBOX链接https://busybox.net/ 点击链接后如图 点击左边菜单栏的Get BusyBix中的Download Source 跳转到busybox 的下载源码…

LabVIEW与PLC点位控制及OPC通讯

在工业自动化中&#xff0c;PLC通过标准协议&#xff08;如Modbus、Ethernet/IP等&#xff09;与OPC Server进行数据交换&#xff0c;LabVIEW作为上位机通过OPC客户端读取PLC的数据并进行监控、控制与处理。通过这种方式&#xff0c;LabVIEW能够实现与PLC的实时通信&#xff0c…

C++ OpenGL学习笔记(1、Hello World空窗口程序)

终于抽出时间系统学习OpenGL 教程&#xff0c;同时也一步一步记录怎样利用openGL进行加速计算。 目录 1、环境准备1.1、库的下载1.2、库的选择及安装 2、OpenGL第一个项目&#xff0c;Hello World!2.1、新建hello world控制台项目2.2、配置openGL环境2.2.1 包含目录配置2.2.2 …

系统移植——Linux 内核顶层 Makefile 详解

一、概述 Linux Kernel网上下载的版本很多NXP等有自己对应的版本。需要从网上直接下载就可以。 二、Linux内核初次编译 编译内核之前需要先在 ubuntu 上安装 lzop 库 sudo apt-get install lzop 在 Ubuntu 中 新 建 名 为 “ alientek_linux ” 的 文 件夹 &#xff0c; …

ubuntu16.04ros-用海龟机器人仿真循线系统

下载安装sudo apt-get install ros-kinetic-turtlebot ros-kinetic-turtlebot-apps ros-kinetic-turtlebot-interactions ros-kinetic-turtlebot-simulator ros-kinetic-kobuki-ftdi sudo apt-get install ros-kinetic-rocon-*echo "source /opt/ros/kinetic/setup.bash…

Connection lease request time out 问题分析

Connection lease request time out 问题分析 问题背景 使用apache的HttpClient&#xff0c;我们知道可以通过setConnectionRequestTimeout()配置从连接池获取链接的超时时间&#xff0c;而Connection lease request time out正是从连接池获取链接超时的报错&#xff0c;这通常…

【文档搜索引擎】在内存中构造出索引结构(上)

文章目录 主要思路正排索引和倒排索引的表示1. 正排索引查询文档详细信息2. 倒排索引中查找关联词3. 新增文档正排索引倒排索引实现词频统计 主要思路 通过 Index 类&#xff0c;在内存中构造出索引结构。这个类要提供的方法&#xff1a; 给定一个 docId&#xff0c;在正排索…

单节点calico性能优化

在单节点上部署calicov3273后&#xff0c;发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点&#xff0c;没有跨节点pod网段组网需要&#xff0c;禁用overlay方式网络(ipip&#xff0c;vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…

tryhackme-Pre Security-HTTP in Detail(HTTP的详细内容)

任务一&#xff1a;What is HTTP(S)?&#xff08;什么是http&#xff08;s&#xff09;&#xff09; 1.What is HTTP? (HyperText Transfer Protocol)&#xff08;什么是 HTTP&#xff1f;&#xff08;超文本传输协议&#xff09;&#xff09; http是你查看网站的时候遵循的…

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…