mysql查询慢Sending data耗时问题

本文分享了一个实际案例,通过调整字段类型一致性、合理使用索引及加入缓存等手段,显著提高了多表关联查询的速度。

背景:刚接手一个完结项目,要性能测试,100w条数据查询时间不超过10s,这个功能的查询是多表关联,现在才几千条数据但是在数据库执行sql的时候发现耗时几十秒,肯定满足不了要求,然后我又是小白,不懂就百度各种大神的经验吧,然后有了一下操作。。。。

一、在navicat中执行了sql 查看下耗时都在 Sending data 中,然后就去看各种大神 怎么去解决,然后就加索引吧,第一次使用索引,就百度了下怎么使用索引。

索引使用:

1.添加PRIMARY KEY(主键索引)

mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) 

2.添加UNIQUE(唯一索引) 

mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 
3.添加INDEX(普通索引) 
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) 
4.添加FULLTEXT(全文索引) 
mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 
5.添加多列索引
mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

然后就想那么多索引类型我选择哪一个,又百度了一下,看到一个mysql性能优化不错,想了下建立了索引,一开始索引名随便取了,后来看大家规范使用了,index_name(name是需要使用索引的字段名) 

mysql explain详解:

这下想着应该会查询很快了,结果,没啥用,然后又查看 在查询开始加explain 查看查询的详情,

然后就去看这些都代表啥,这个MySQL explain详解不错,了解到key有null,说明这个表的索引没用上,而且还是大量数据的表,就去查看啥原因。看到,可以加上force index(强制要走的那个索引)可以强制使用索引,也就加上试试了,顺带几下两个使用例子:

select * from table force index(ziduan1_index) limit 2;(强制使用索引"ziduan1_index")
select * from table ignore index(ziduan1_index) limit 2;(禁止使用索引"ziduan1_index")

好了继续执行sql结果还是不行,耗时没啥变化,再去查看,索引还是没用上,不懂了。。。。

关联字段类型不同:

又百度,后来看到一个说关联表的字段类型不一致也会导致查询慢。然后就去一个一个去查看关联字段。结果发现两张表一个是int 一个是varchar,然后就改一样的呗,果然,查询速度立马上来了。这次只要1秒了。再次访问竟然只要0.02秒r,很神奇,结果发现MySQL可以缓存,私下研究了。

缓存:

之前做的项目使用了redis缓存,然后也想这个也加上是不是更好,感觉spring boot 集成redis挺方便的,就加上的redis,为了提高性能,又在前端每次分页查看的时候把数据也缓存下来。多重使用,效果果然提升了好多。。。

总结:度娘是个好东西!!!!


<think>嗯,用户遇到了MySQL的'sending data'状态耗时过长的问题,需要解决。首先,我需要回忆一下'sending data'状态具体指的是什么。根据之前的知识,这个状态通常出现在查询执行期间,涉及到从存储引擎读取数据并通过网络发送给客户端的过程。可能的原因有很多,比如查询效率低、索引缺失、数据量过大、网络问题或者服务器配置不当。 接下来,我应该按照系统级指令的要求,结构清晰、分步骤解答。需要引用提供的参考内容,比如引用[3]提到的使用LOAD DATA INFILE而不是INSERT来加快数据加载,这可能和优化数据导入有关,但用户的问题是关于查询阶段的,所以可能需要其他优化手段。 首先,分析问题可能的原因。用户提到'sending data'耗时过长,这通常意味着查询需要处理大量数据,或者存在全表扫描。这时候,检查查询的执行计划是关键,查看是否有合适的索引被使用。比如,如果WHERE子句中的列没有索引,可能会导致全表扫描,增加数据读取时间,从而延长'sending data'状态。 然后,考虑索引优化。参考引用[3]中的优化建议,虽然没有直接提到索引,但合理的索引可以显著减少数据扫描量。需要建议用户添加必要的索引,尤其是复合索引,以覆盖查询所需的列。 接下来,优化查询语句。比如避免使用SELECT *,只选择需要的列,减少传输的数据量。同时,检查是否有不必要的JOIN或者子查询,这些都可能增加处理时间。此外,分页查询时使用LIMIT和OFFSET可能导致性能问题,可以改用基于游标的分页方法。 服务器和网络配置也是一个方面。比如调整max_allowed_packet参数,确保网络带宽足够,减少延迟。硬件方面,如果磁盘I/O成为瓶颈,升级SSD可能会有帮助。 另外,参考引用[1]中的show profiles,建议用户使用性能分析工具,如EXPLAIN或SHOW PROFILE,来定位具体耗时环节。比如,执行EXPLAIN分析查询计划,查看是否有全表扫描或临时表的使用。SHOW PROFILE可以显示各个阶段的耗时,确认'sending data'阶段的具体时间占比。 同时,需要考虑数据量的问题。如果单次查询返回大量数据,是否可以考虑分页或者分批处理。引用[3]提到的LOAD DATA INFILE虽然主要针对数据导入,但也提示了批量处理的重要性,可能间接影响查询效率。 最后,系统参数调优,比如调整innodb_buffer_pool_size,确保足够的内存来缓存数据和索引,减少磁盘I/O。连接线程配置如thread_cache_size也可能影响性能,但需要根据具体情况调整。 总结下来,解决方案应该包括检查执行计划、优化索引、精简查询、调整服务器配置、分析性能和使用工具定位问题。可能需要结合多个方面来综合解决'sending data'耗时过长的问题。同时,生成的相关问题要围绕这些方面,比如如何分析执行计划、优化索引的方法、服务器参数调整等。</think>### MySQL 'sending data' 状态耗时过长解决方案 `sending data` 是MySQL查询执行过程中的一个状态,表示服务器正在从存储引擎读取数据并通过网络发送给客户端[^2]。若此阶段耗时过长,可通过以下步骤排查和优化: --- #### 一、问题定位 1. **分析执行计划** 使用 `EXPLAIN` 查看SQL的执行计划,重点关注以下字段: - `type`:若为 `ALL` 表示全表扫描,需优化索引 - `rows`:扫描的行数,数值过大需优化查询条件 - `Extra`:若出现 `Using temporary` 或 `Using filesort`,需调整查询索引 示例: ```sql EXPLAIN SELECT * FROM payment WHERE customer_id = 100; ``` 2. **性能分析工具** 使用 `SHOW PROFILE` 或 `SHOW PROFILES` 定位耗时阶段(需先启用性能分析): ```sql SET profiling = 1; SELECT * FROM payment WHERE amount > 10; SHOW PROFILES; -- 查看Query_ID SHOW PROFILE FOR QUERY 1; -- 详细阶段耗时[^1] ``` --- #### 二、优化方法 1. **索引优化** - **添加缺失索引**:为 `WHERE`、`JOIN`、`ORDER BY` 涉及的列创建索引 ```sql ALTER TABLE payment ADD INDEX idx_customer_amount (customer_id, amount); ``` - **避免冗余索引**:定期使用 `SHOW INDEX FROM table` 分析索引使用率 2. **查询语句优化** - **减少返回数据量**:避免 `SELECT *`,仅选择必要字段 - **分页优化**:使用 `WHERE id > {last_id}` 替代 `LIMIT offset, size` - **避免复杂子查询**:改用 `JOIN` 或临时表 3. **服务器与网络优化** - **调整 `max_allowed_packet`**:增大网络传输包大小限制 - **检查网络延迟**:通过 `ping` 或 `traceroute` 分析客户端与服务器的网络质量 - **升级硬件**:使用SSD替代HDD,提高I/O性能 --- #### 三、系统参数调优 1. **InnoDB缓冲池** 调整 `innodb_buffer_pool_size`(通常设为物理内存的70%~80%): ```ini [mysqld] innodb_buffer_pool_size = 4G ``` 2. **线程与连接配置** ```ini thread_cache_size = 16 -- 减少线程创建开销 max_connections = 200 -- 根据实际负载调整 ``` --- #### 四、其他建议 - **批量操作优化**:对大量数据写入使用 `LOAD DATA INFILE`(比 `INSERT` 快20倍)[^3] - **定期维护表**:执行 `OPTIMIZE TABLE payment` 整理碎片 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值