数据量增加导致mysql执行计划改变解决_MySQL
bitsCN.com
数据量增加导致mysql执行计划改变解决
收到运维同学电话,mysql服务器连接数满了,登录服务器查看,确实满了,好吧,首先增加连接数到2500,暂时提供对外服务。连接继续升高,又快达到2500。发现有大量的查询时间将近到了1200秒,大量的长连接堆积,导致连接数攀升,看来还是sql的问题。在这些长连接中,发现这样的sql
SELECT product_id,gift_id,gift_original_price,gift_count, FROM promo_xxx WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;mysql> explain SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1;+----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE | promo_gift_list | ALL | id_promo_gift | NULL | NULL | NULL | 249188 | Using where | +----+-------------+-----------------+------+---------------+------+---------+------+--------+-------------+1 row in set (0.04 sec)mysql> show index from promo_gift;+-----------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |+-----------------+------------+-----------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+| promo_gift_list | 0 | PRIMARY | 1 | id | A | 261184 | NULL | NULL | | BTREE | | | | promo_gift_list | 0 | id_promo_gift | 1 | promotion_id | A | 1140 | NULL | NULL | YES | BTREE | | | | promo_gift_list | 0 | id_promo_gift | 4 | product_id | A | 261184 | NULL | NULL | YES | BTREE | | |
狗血的sql,竟然走全表扫描,但是promotion_id有索引啊,为什么没有走索引呢?而且以前建立的索引,走的好好的,今天怎么就出现问题了,这是一个问题
那我们可以通过last_query_cost 查看sql消耗
mysql>SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1; mysql>show status like 'last_query_cost';+-----------------+--------------+| Variable_name | Value |+-----------------+--------------+| Last_query_cost | 52626.599000 | +-----------------+--------------+1 row in set (0.00 sec)
不走索引,那我们强制使用索引
mysql> explain SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift force index(id_promo_gift) WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1; +----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+| 1 | SIMPLE | promo_gift_list | range | id_promo_gift | id_promo_gift | 5 | NULL | 124594 | Using where | +----+-------------+-----------------+-------+---------------+---------------+---------+------+--------+-------------+1 row in set (0.02 sec)
嗯,加上索引了,那么sql消耗怎么样呢?
mysql> SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift force index(id_promo_gift) WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1; +------------+----------+---------------------+------------+| product_id | gift_id | gift_original_price | gift_count |+------------+----------+---------------------+------------+| 22569455 | 23230046 | 147.00 | 1 | +------------+----------+---------------------+------------+1 row in set (0.40 sec)mysql> show status like 'last_query_cost';+-----------------+---------------+| Variable_name | Value |+-----------------+---------------+| Last_query_cost | 174432.609000 | +-----------------+---------------+1 row in set (0.00 sec)
我们发现如果使用这个索引,sql消耗174432.609000>52626.599000,mysql优化器认为使用这个id_promo_gift索引,sql消耗是非常大的,这就是mysql执行不使用这个索引的原因。
后来开发人员说,昨天晚上这个表增加了11万多的数据,嗯,数据量增加,mysql执行计划改变。那好吧,单独product_id列再加一个索引。
mysql> alter table promo_gift_list add index product_id(product_id);Query OK, 0 rows affected (6.45 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> explain SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift_list WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1 AND IFNULL(is_delete,0)!=1;+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+| 1 | SIMPLE | promo_gift_list | ref | id_promo_gift,product_id | product_id | 5 | const | 2 | Using where |+----+-------------+-----------------+------+--------------------------+------------+---------+-------+------+-------------+1 row in set (0.00 sec)
使用了刚才新加的索引 product_id
mysql> SELECT product_id,gift_id,gift_original_price,gift_count FROM promo_gift_list WHERE promotion_id IN (589994,589994) AND product_id IN (22569455) AND is_valid=1 AND IFNULL(is_delete,0)!=1; +------------+----------+---------------------+------------+| product_id | gift_id | gift_original_price | gift_count |+------------+----------+---------------------+------------+| 22569455 | 23230046 | 147.00 | 1 | +------------+----------+---------------------+------------+1 row in set (0.00 sec)mysql> show status like 'last_query_cost';+-----------------+----------+| Variable_name | Value |+-----------------+----------+| Last_query_cost | 2.399000 | +-----------------+----------+1 row in set (0.01 sec)
sql消耗降到了2.399000,ok,问题解决。连接数很快从1000多降到100以内。
数据量的增加导致了mysql执行计划的改变,那么mysql的cost是怎么计算的呢?
cost=io_cost+cpu_cost
cpu_cost位于mysql上层,处理返回的记录所花开销,io_cost存储引擎层,读取也没的IO开销。最直接的方式last_query_cost记录sql的cost。查看last_query_cost可以初步判断sql的cost,明白mysql优化器执行的依据。
bitsCN.com

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

在PHP中备份和还原MySQL数据库可通过以下步骤实现:备份数据库:使用mysqldump命令转储数据库为SQL文件。还原数据库:使用mysql命令从SQL文件还原数据库。

可以通过以下方式优化MySQL查询性能:建立索引,将查找时间从线性复杂度降至对数复杂度。使用PreparedStatements,防止SQL注入并提高查询性能。限制查询结果,减少服务器处理的数据量。优化连接查询,包括使用适当的连接类型、创建索引和考虑使用子查询。分析查询,识别瓶颈;使用缓存,减少数据库负载;优化PHP代码,尽量减少开销。

如何将数据插入MySQL表中?连接到数据库:使用mysqli建立与数据库的连接。准备SQL查询:编写一个INSERT语句以指定要插入的列和值。执行查询:使用query()方法执行插入查询,如果成功,将输出一条确认消息。

使用PHP创建MySQL表需要以下步骤:连接到数据库。创建数据库(如果不存在)。选择数据库。创建表。执行查询。关闭连接。

要在PHP中使用MySQL存储过程:使用PDO或MySQLi扩展连接到MySQL数据库。准备调用存储过程的语句。执行存储过程。处理结果集(如果存储过程返回结果)。关闭数据库连接。

MySQL 8.4(截至 2024 年的最新 LTS 版本)中引入的主要变化之一是默认情况下不再启用“MySQL 本机密码”插件。此外,MySQL 9.0完全删除了这个插件。 此更改会影响 PHP 和其他应用程序

Oracle数据库和MySQL都是基于关系模型的数据库,但Oracle在兼容性、可扩展性、数据类型和安全性方面更胜一筹;而MySQL则侧重速度和灵活性,更适合小到中等规模的数据集。①Oracle提供广泛的数据类型,②提供高级安全功能,③适合企业级应用程序;①MySQL支持NoSQL数据类型,②安全性措施较少,③适合小型到中等规模应用程序。

本站7月23日消息,华硕推出多款由AMDEPYC霄龙4004系列处理器驱动的服务器与工作站级产品。本站注:AMD于5月推出AM5平台、Zen4架构的EPYC霄龙4004系列处理器,最高提供16核3DV-Cache规格。ASUSProER100AB6服务器ASUSProER100AB6是一款搭载EPYC霄龙4004系列处理器的1U机架式服务器产品,适用于IDC及中小型企业需求。ASUSExpertCenterProET500AB6工作站ASUSExpertCenterProET500AB6是一款A
