Wishlist 0 ¥0.00

轻松上手MYSQL:优化MySQL慢查询,让数据库起飞

文章目录

 

Part1、认识MYSQL慢查询 ?

    
    在MySQL数据库中,慢查询(Slow Query)通常指的是执行时间超过预设阈值的查询语句。这些查询可能会消耗大量的数据库资源,导致系统性能下降或响应时间延长。因此,监控和优化慢查询是数据库管理员(DBA)和开发人员的重要任务之一。
 
慢查询的影响
 

  • 性能瓶颈:慢查询会消耗大量的CPU、内存和I/O资源,导致数据库性能下降。
  • 响应时间:用户请求的响应时间可能会因为慢查询而延长,影响用户体验。
  • 资源浪费:不必要的慢查询会浪费数据库服务器的资源,降低整体系统的稳定性。

 

Part2、配置和识别慢查询 ?

 

开启慢查询监控

    mysql有一个配置是long_query_time,值是数字,单位是秒。当一条SQL语句执行耗时超过long_query_time的值时,mysql就认为这条sql为慢查询SQL。
 

临时配置
 
    找开命令窗口配置

// 查看慢查询是否开启
show variables like 'slow_query_log';
// 开启慢查询(值可以是1或on)
set global slow_query_log = 1;
// 关闭慢查询(值可以是1或off)
set global slow_query_log = 0;
 
// 查看long_query_time值
show variable like 'long_query_time';
// 设置long_query_time值 (单位是秒)
set global long_query_time=5;

 

永久生效配置
 
    MySQL的配置文件(通常是 my.cnf 或 my.ini)
    如果你还没有启用慢查询日志,你还需要在配置文件中设置 slow_query_log 为 ON,并指定一个日志文件路径(如果需要的话)。

[mysqld]  
// 启用慢查询日志
slow_query_log = 1  
// 指定日志文章路径
slow_query_log_file = /var/log/mysql/mysql-slow.log  
// 开启慢查询
long_query_time = 2

    注:此配置需要重启mysql服务
 

Part3、分析慢查询原因 ?

 
    引起慢查询的原因大致归纳如下:

  1. 没有索引或索引不生效:
    • 没有在适当的列上建立索引,导致MySQL执行全表扫描。
    • 索引设计不合理或查询条件导致索引失效,如隐式类型转换、查询条件包含OR等。
  2. I/O吞吐量小:
    • 磁盘I/O成为瓶颈,导致数据读取速度缓慢。
  3. 内存不足:
    • MySQL需要频繁地进行磁盘I/O操作以获取数据,降低了查询速度。
  4. 网络速度慢:
    • 对于远程数据库连接,网络延迟可能导致查询响应缓慢。
  5. 查询出的数据量过大:
    • 查询返回的结果集过大,增加了数据传输和处理的时间。
  6. 锁或死锁:
    • 查询时遇到表锁、行锁或其他类型的锁,导致查询被阻塞或延迟。
  7. 查询语句未优化:
    • 查询语句编写不合理,如使用了不必要的子查询、复杂的连接条件等。
  8. 硬件资源限制:
    • CPU、内存、磁盘等硬件资源不足或配置不合理,影响MySQL性能。
       

Part4、解决和避免慢查询

 

  • 提高网速、更换更高容量的硬盘、增加内存或者 cpu 的数量等等。
  • 调整配置参数:mysql 有许多参数可以配置,可以根据实际情况调整这些参数,如增加缓存大小、线程池大小等等。
  • 添加索引:索引可以提高查询效率,特别是对于大型表。通过分析慢查询日志或者使用 explain 命令找到需要优化的查询语句,然后为其中涉及的列添加索引(注意不要添加过多的索引)。
  • 优化查询语句:合理优化查询语句可以减少查询时间。例如,可以尝试减少子查询的数量,避免使用SELECT *,多表JOIN,避免使用 like ‘%xxx%’ 的模糊查询等。
  • 批量处理数据:有时候大量数据的操作往往比单个数据的操作更有效率。因此,尽可能以批量方式操作数据,如使用 insert … values() 和 update … set … where in() 等。
  • 分库分表:若数据量较大,可能会对单个数据库的性能造成压力。此时可以考虑将数据分散存储到多个数据库中,或者将单张表的数据拆分为多张表来存储。注意,这种方法需要谨慎设计,在实际应用中可能会引入更多的问题。
  • 表中的大字段剥离。
  • 字段冗余。
  • 减少sql中函数运算与其他计算。
  • 修改SQL语句:优化查询语句,避免使用SELECT *、子查询、多表JOIN等不必要的操作。
  • 数据库优化:调整数据库参数、内存占用、磁盘IO等,提高系统性能,增加查询效率。
  • 针对查询频繁的热点数据增加缓存,引入非关系型数据库。
  • 主从复制,读写分离,一般情况下,查询的情况比写的情况多,所以考虑将数据库分为主库,从库,主库处理写的操作,从库处理读的操作。
     

总结 ?

 
    在MySQL数据库中,慢查询是一个不容忽视的问题,它不仅会消耗大量的系统资源,还可能导致系统性能下降和用户体验变差。因此,有效地识别、分析和解决慢查询问题是数据库管理员和开发人员的重要职责。
 
    首先,我们需要通过配置MySQL的慢查询日志功能来监控慢查询。这包括临时配置和永久配置两种方式,其中永久配置需要在MySQL的配置文件中设置相关参数,并确保MySQL服务重启后配置生效。
 
    其次,当慢查询发生时,我们需要分析其原因。常见的原因包括没有索引或索引不生效、I/O吞吐量小、内存不足、网络速度慢、查询出的数据量过大、锁或死锁、查询语句未优化以及硬件资源限制等。
 
    针对这些原因,我们可以采取一系列措施来解决和避免慢查询。这些措施包括提高网络速度、更换高容量硬盘、增加内存或CPU数量等硬件升级措施;调整MySQL的配置参数,如增加缓存大小、线程池大小等;为查询涉及的列添加合适的索引;优化查询语句,减少不必要的子查询和复杂的连接条件;批量处理数据以减少I/O操作;分库分表以分散存储数据;剥离表中的大字段以减少数据传输和处理时间;减少SQL中的函数运算和其他计算;针对热点数据增加缓存;引入主从复制和读写分离策略等。
 
    总之,解决慢查询问题需要从多个方面入手,包括硬件配置、MySQL配置、索引设计、查询优化以及数据库架构等方面。只有综合考虑并采取合适的措施,才能有效地提高MySQL的性能和稳定性,确保用户获得良好的体验。

轻松上手MYSQL:优化MySQL慢查询,让数据库起飞

 

 

欢迎加入探索MYSQL慢查询之旅
    ? 大家好!我是你们的技术达人danci_btq。你是否因为MYSQL慢查询而头疼不已?今天我来教你如何高效地优化这些慢查询,让你的数据库飞速跑!? 在本文中,我们将探索一些简单而有效的方法,让你轻松应对MYSQL慢查询问题。准备好了吗?Let’s go!?

 

 

Part1、认识MYSQL慢查询 ?

    
    在MySQL数据库中,慢查询(Slow Query)通常指的是执行时间超过预设阈值的查询语句。这些查询可能会消耗大量的数据库资源,导致系统性能下降或响应时间延长。因此,监控和优化慢查询是数据库管理员(DBA)和开发人员的重要任务之一。
 
慢查询的影响
 

  • 性能瓶颈:慢查询会消耗大量的CPU、内存和I/O资源,导致数据库性能下降。
  • 响应时间:用户请求的响应时间可能会因为慢查询而延长,影响用户体验。
  • 资源浪费:不必要的慢查询会浪费数据库服务器的资源,降低整体系统的稳定性。

 

Part2、配置和识别慢查询 ?

 

开启慢查询监控

    mysql有一个配置是long_query_time,值是数字,单位是秒。当一条SQL语句执行耗时超过long_query_time的值时,mysql就认为这条sql为慢查询SQL。
 

临时配置
 
    找开命令窗口配置

// 查看慢查询是否开启
show variables like 'slow_query_log';
// 开启慢查询(值可以是1或on)
set global slow_query_log = 1;
// 关闭慢查询(值可以是1或off)
set global slow_query_log = 0;
 
// 查看long_query_time值
show variable like 'long_query_time';
// 设置long_query_time值 (单位是秒)
set global long_query_time=5;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

 

永久生效配置
 
    MySQL的配置文件(通常是 my.cnf 或 my.ini)
    如果你还没有启用慢查询日志,你还需要在配置文件中设置 slow_query_log 为 ON,并指定一个日志文件路径(如果需要的话)。

[mysqld]  
// 启用慢查询日志
slow_query_log = 1  
// 指定日志文章路径
slow_query_log_file = /var/log/mysql/mysql-slow.log  
// 开启慢查询
long_query_time = 2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

    注:此配置需要重启mysql服务
 

Part3、分析慢查询原因 ?

 
    引起慢查询的原因大致归纳如下:

  1. 没有索引或索引不生效:
    • 没有在适当的列上建立索引,导致MySQL执行全表扫描。
    • 索引设计不合理或查询条件导致索引失效,如隐式类型转换、查询条件包含OR等。
  2. I/O吞吐量小:
    • 磁盘I/O成为瓶颈,导致数据读取速度缓慢。
  3. 内存不足:
    • MySQL需要频繁地进行磁盘I/O操作以获取数据,降低了查询速度。
  4. 网络速度慢:
    • 对于远程数据库连接,网络延迟可能导致查询响应缓慢。
  5. 查询出的数据量过大:
    • 查询返回的结果集过大,增加了数据传输和处理的时间。
  6. 锁或死锁:
    • 查询时遇到表锁、行锁或其他类型的锁,导致查询被阻塞或延迟。
  7. 查询语句未优化:
    • 查询语句编写不合理,如使用了不必要的子查询、复杂的连接条件等。
  8. 硬件资源限制:
    • CPU、内存、磁盘等硬件资源不足或配置不合理,影响MySQL性能。
       

Part4、解决和避免慢查询

 

  • 提高网速、更换更高容量的硬盘、增加内存或者 cpu 的数量等等。
  • 调整配置参数:mysql 有许多参数可以配置,可以根据实际情况调整这些参数,如增加缓存大小、线程池大小等等。
  • 添加索引:索引可以提高查询效率,特别是对于大型表。通过分析慢查询日志或者使用 explain 命令找到需要优化的查询语句,然后为其中涉及的列添加索引(注意不要添加过多的索引)。
  • 优化查询语句:合理优化查询语句可以减少查询时间。例如,可以尝试减少子查询的数量,避免使用SELECT *,多表JOIN,避免使用 like ‘%xxx%’ 的模糊查询等。
  • 批量处理数据:有时候大量数据的操作往往比单个数据的操作更有效率。因此,尽可能以批量方式操作数据,如使用 insert … values() 和 update … set … where in() 等。
  • 分库分表:若数据量较大,可能会对单个数据库的性能造成压力。此时可以考虑将数据分散存储到多个数据库中,或者将单张表的数据拆分为多张表来存储。注意,这种方法需要谨慎设计,在实际应用中可能会引入更多的问题。
  • 表中的大字段剥离。
  • 字段冗余。
  • 减少sql中函数运算与其他计算。
  • 修改SQL语句:优化查询语句,避免使用SELECT *、子查询、多表JOIN等不必要的操作。
  • 数据库优化:调整数据库参数、内存占用、磁盘IO等,提高系统性能,增加查询效率。
  • 针对查询频繁的热点数据增加缓存,引入非关系型数据库。
  • 主从复制,读写分离,一般情况下,查询的情况比写的情况多,所以考虑将数据库分为主库,从库,主库处理写的操作,从库处理读的操作。
     

总结 ?

 
    在MySQL数据库中,慢查询是一个不容忽视的问题,它不仅会消耗大量的系统资源,还可能导致系统性能下降和用户体验变差。因此,有效地识别、分析和解决慢查询问题是数据库管理员和开发人员的重要职责。
 
    首先,我们需要通过配置MySQL的慢查询日志功能来监控慢查询。这包括临时配置和永久配置两种方式,其中永久配置需要在MySQL的配置文件中设置相关参数,并确保MySQL服务重启后配置生效。
 
    其次,当慢查询发生时,我们需要分析其原因。常见的原因包括没有索引或索引不生效、I/O吞吐量小、内存不足、网络速度慢、查询出的数据量过大、锁或死锁、查询语句未优化以及硬件资源限制等。
 
    针对这些原因,我们可以采取一系列措施来解决和避免慢查询。这些措施包括提高网络速度、更换高容量硬盘、增加内存或CPU数量等硬件升级措施;调整MySQL的配置参数,如增加缓存大小、线程池大小等;为查询涉及的列添加合适的索引;优化查询语句,减少不必要的子查询和复杂的连接条件;批量处理数据以减少I/O操作;分库分表以分散存储数据;剥离表中的大字段以减少数据传输和处理时间;减少SQL中的函数运算和其他计算;针对热点数据增加缓存;引入主从复制和读写分离策略等。
 
    总之,解决慢查询问题需要从多个方面入手,包括硬件配置、MySQL配置、索引设计、查询优化以及数据库架构等方面。只有综合考虑并采取合适的措施,才能有效地提高MySQL的性能和稳定性,确保用户获得良好的体验。

更改Joomla的网站图标

改變您的網頁 favicon 是一件容易的事。

Favicon-en

  1. 製作一個 16x16 或 32x32 解析度的圖片。 您可以使用一些圖像編輯軟體來製作,例如 PhotoshopGimpPaint.net 或 Windows Paint。當然,你也可以使用一些線上工具如 http://antifavicon.com/
  2. 更改為 ico 格式 使用免費的線上工具例如:
  1. 利用以上方法建立的檔案,其副檔名將會是 .ico。複製該檔案/joomla/templates/<your template>目錄並且將它命名為favicon.ico
  2. 開啟瀏覽器。有看到新的圖示了嗎?如果有,那真是太好了。但若是沒有,也不一定代表你做錯哪一個步驟喔。瀏覽器通常都設計為最大限度地減少網路流量,所以它們基本上不會在你按下每一次的重新整理(F5)後就立刻顯示你更改過的 favicon。因此,若想立刻看到變更過的 favicon 您可能會需要使用以下方法:
    • Mozilla / Firefox / Safari:按住 Shift 鍵並點擊重新整理,或按 Ctrl-Shift-R (Mac:Cmd-Shift-R);
    • IE:按住 Ctrl 鍵並點擊重新整理,或按 Ctrl-F5;
    • Konqueror:直接點擊重新整理,或按 F5;
    • Opera:使用者基本上需要到 工具 選項 中去完全地清除快取;
    • Chrome:Shift-F5;
    • 如果上述方式沒用的話,你將需要到各瀏覽器中的設定裡去刪除它們的快取檔案及歷史紀錄並重新開啟您的頁面。或刪除您的 favicon,按下 F5 重新整理瀏覽器,再去上傳 favicon。

我的 favicon 位於其他地方

有些佈景主題會包含一些代碼來讓瀏覽器重新導向至其他的目錄或其他圖示檔案。如要確認您的新 favicon 應該在哪裡,請檢查http://yoursite.com/templates/your_template/index.php並查看原始碼是否有包含該字段<link rel="shortcut icon"。您將可以從此來找到該圖示的目錄以及它的檔名。複製您要用的圖示到它指定的路徑,並給它連結指向的名稱(您可能會需要先備份舊檔案)。請確定你已設定了正確的安全性來讓您的網頁伺服器可以有權限訪問該檔案。請看以下範例:

<link rel="shortcut icon" href="http://yoursite.com/templates/your_template/icon/favicon.ico" />

但如果您不想只變更各佈景主題目錄中的 favicon.ico 檔案,那麼您可以到 html.php 中找到對 favicon.ico 檔案的引用。其路徑為 "........\libraries\joomla\document\html\html.php"。這樣做可避免圖示被切換:

<link rel="shortcut icon" href="http://yoursite.com/templates/your_template/icon/youricon.ico" />

在佈景主題 html 中,並且您不用刪除 favicon.ico 檔案。(為何要叫兩次 icon?)

從 html.php 中

// Try to find a favicon by checking the template and root folder
		$path = $directory . DS;
		$dirs = array( $path, JPATH_BASE . DS );
		foreach ($dirs as $dir )
		{
			$icon =   $dir . 'favicon.ico';
			if (file_exists( $icon ))
			{
				$path = str_replace( JPATH_BASE . DS, '', $dir );
				$path = str_replace( '\\', '/', $path );
				$this->addFavicon( JURI::base(true).'/'.$path . 'favicon.ico' );
				break;''

MySQL的系统变量max_execution_time小结

参数介绍:

MySQL社区版MySQL 5.7.8开始,新增了MAX_EXECUTION_TIME这个系统变量,它用来限制SQL语句的执行时间,确切来说是限制只读SELECT语句。如果查询语句的执行时长超过这个阈值,MySQL将自动停止该SQL语句的执行。如果其值为 0,表示不启用该超时限制功能。该参数/变量单位是毫秒(milliseconds),千万要注意,单位是毫秒。不是秒。

官方文档[1]关于系统变量max_execution_time的描述如下:

The execution timeout for SELECT statements, in milliseconds. If the value is 0, timeouts are not enabled.

max_execution_time applies as follows:

The global max_execution_time value provides the default for the session value for new connections. The session value applies to SELECT executions executed within the session that include no MAX_EXECUTION_TIME(N) optimizer hint or for which N is 0.

max_execution_time applies to read-only SELECT statements. Statements that are not read only are those that invoke a stored function that modifies data as a side effect.

max_execution_time is ignored for SELECT statements in stored programs.or SELECT statements in stored programs.

注意事项:

  1. max_execution_time只对只读的select有效,对DDL及UPDATE、DELETE等DML操作不生效
  2. 只有顶层(即不是子查询)SQL受到影响
  3. 存储程序中的 SELECT 语句,不受影响。即使存储过程中SELECT语句使用MAX_EXECUTION_TIME提示也不受影响

生产环境较常见的情况是,由于没有正确配置JDBC等驱动,导致业务代码已经超时退出了与数据库的交互,但是数据库里依旧运行着发起的SQL,如果频繁发起重试,则慢SQL会越来越多,导致数据库负载高,影响稳定性及可用性。因此,建议设置参数max_execution_time来解决这种情况。但是,由于生产环境的复杂性,需要跟开发人员先协商,另外,这个值可能需要设置的相对大一些,避免影响业务。总之来说是谨慎使用。

其实在MySQL 5.6的时候,其他分支版本(从所查资料来看,最开始是twitter的分支版本[2]引入的,也被Percona Server 5.6分支版本并入)引入了系统变量max_statement_time来控制MySQL的最长执行时间。如果超过该系统变量的值,查询将会自动失败,默认是不限制。

不过MySQL社区版在MySQL 5.6并未引入这个系统变量,从社区版MySQL 5.7.4开始,才开始引入了系统变量max_statement_time。不过这个系统变量在MySQL 5.7.8被移除。具体可以参考官方文档[3]。其实这个系统变量之所以在MySQL 5.7.8被移除,是因为用系统变量max_execution_time替换了系统变量max_statement_time

  • max_statement_time: Statement execution timeout value. Added in MySQL 5.7.4.
  • max_statement_time: Statement execution timeout value. Removed in MySQL 5.7.8.

参数设置

全局级别

方法1.在参数文件my.cnf中设置

max_execution_time=20000

注意:这种方法,需要重启MySQL数据库实例才能生效。

方法2:

mysql> set global max_execution_time=20000;
Query OK, 0 rows affected (0.00 sec)

注意,设置全局系统变量后,对当前会话不生效,正确来说已经建立连接的会话是不生效的,它只对全局系统变量设置后,新建立的会话生效。如下所示,另外,重启后会系统变量值会失效。

mysql> show variables like 'max_execution_time';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| max_execution_time | 0     |
+--------------------+-------+
1 row in set (0.00 sec)

mysql> 
mysql> select  @@global.max_execution_time, @@session.max_execution_time;

如果想重启后也能生效,可以使用下面SQL设置

mysql> set persist max_execution_time=20000;
Query OK, 0 rows affected (0.01 sec)

会话级别

mysql> set max_execution_time=1000;
Query OK, 0 rows affected (0.00 sec)

SQL语句级别

其实这里使用HINT来限制SELECT查询的最大时长,也的确是在语句级别执行限制。

SELECT /*+ MAX_EXECUTION_TIME(3000) */ * FROM table_name;

上述SQL语句表示,执行该查询,并设置执行时间为3秒,在超时时间到达时,MySQL将自动停止该查询的执行。注意:该选项只在使用InnoDB的默认存储引擎时有效,如果需要在其他存储引擎中使用该选项,请自行查阅文档或手册。

mysql>  SELECT /*+ MAX_EXECUTION_TIME(2000) */ * FROM TEST;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
mysql> 

参考资料

[1]

1: https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_execution_time

[2]

2: https://github.com/twitter-forks/mysql/wiki/Statement-Timeout

[3]

3: https://dev.mysql.com/doc/refman/5.7/en/added-deprecated-removed.html

About Us

Since 1996, our company has been focusing on domain name registration, web hosting, server hosting, website construction, e-commerce and other Internet services, and constantly practicing the concept of "providing enterprise-level solutions and providing personalized service support". As a Dell Authorized Solution Provider, we also provide hardware product solutions associated with the company's services.
 

Contact Us

Address: No. 2, Jingwu Road, Zhengzhou City, Henan Province

Phone: 0086-371-63520088 

QQ:76257322

Website: 800188.com

E-mail: This email address is being protected from spambots. You need JavaScript enabled to view it.