【数据库】【Mysql】慢SQL深度分析:EXPLAIN 与 optimizer_trace 全解析

MySQL 慢SQL深度分析:EXPLAIN 与 optimizer_trace 全解析

在 MySQL 性能优化体系中,慢SQL分析是核心技能。本文将从EXPLAIN 执行计划解读optimizer_trace 优化器追踪,构建完整的慢查询诊断方法论。


一、EXPLAIN 基础与核心字段总览

1.1 EXPLAIN 使用方法

基础语法

-- 分析 SELECT 语句EXPLAINSELECT*FROMordersWHEREuser_id=100;-- 获取 JSON 格式详细计划(推荐用于复杂分析)EXPLAINFORMAT=JSONSELECT*FROMordersWHEREuser_id=100;-- 分析 UPDATE/DELETE(MySQL 5.6+)EXPLAINUPDATEordersSETstatus='paid'WHEREuser_id=100;

关键输出字段

+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+|id|select_type|table|partitions|type|possible_keys|key|key_len|ref|rows|filtered|Extra|+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-------------+

分析优先级type → key → rows → Extra,这四个字段决定了查询性能基线。


二、type 字段详解:访问类型优化路径

type 字段表示表连接类型,是判断查询效率的核心指标,性能从好到差排序如下:

2.1 最优类型:system 与 const

system:表中仅有一条数据,是const类型的特例

-- 示例:系统配置表仅一行EXPLAINSELECT*FROMconfigWHEREid=1;

const:使用主键或唯一索引进行等值匹配,最多返回一条记录

-- 示例:主键等值查询EXPLAINSELECT*FROMusersWHEREid=100;-- type: const

性能特征:这些类型代表单表访问,性能最优,查询时间为常量级

2.2 高效类型:eq_ref 与 ref

eq_ref:连接查询中,驱动表通过唯一索引访问被驱动表

-- 示例:employees 表通过主键关联 salaries 表EXPLAINSELECTe.*,s.salaryFROMemployees eJOINsalaries sONe.emp_no=s.emp_no;-- s 表 type: eq_ref

ref:使用非唯一索引进行等值匹配,可能返回多条记录

-- 示例:通过普通索引查询EXPLAINSELECT*FROMordersWHEREuser_id=100;-- type: ref

优化目标核心业务 SQL 至少达到 ref 级别

2.3 中等类型:range 与 index

range:索引范围扫描,常用于>,<,BETWEEN,IN等操作

-- 示例:时间范围查询EXPLAINSELECT*FROMordersWHEREcreate_timeBETWEEN'2024-01-01'AND'2024-01-31';

index:全索引扫描,遍历整个索引树,比全表扫描快

-- 示例:查询索引列(无需回表)EXPLAINSELECTuser_idFROMorders;-- 只查索引列

注意index虽然比ALL快,但对大表仍是性能隐患。

2.4 最差类型:ALL(全表扫描)

ALL:全表扫描,必须优化

-- 示例:无索引或索引失效EXPLAINSELECT*FROMordersWHEREYEAR(create_time)=2024;-- type: ALLEXPLAINSELECT*FROMordersWHEREstatus='shipped';-- status 无索引

优化路径

  1. 添加索引:为 WHERE 条件列创建索引
  2. 避免函数YEAR(create_time)create_time >= '2024-01-01'
  3. 强制索引FORCE INDEX(idx_create_time)

2.5 type 优化检查清单

type 类型性能等级是否需要优化典型场景
system★★★★★无需单行配置表
const★★★★★无需主键等值查询
eq_ref★★★★★无需JOIN 主键关联
ref★★★★☆可接受普通索引等值查询
range★★★☆☆观察小范围查询
index★★☆☆☆建议优化全索引扫描
ALL★☆☆☆☆必须优化全表扫描

三、ref、rows、filtered 字段深度解读

3.1 ref:索引引用列

含义:显示哪些列或常量被用于索引查找

-- 示例:常量引用EXPLAINSELECT*FROMordersWHEREuser_id=100;-- ref: const-- 示例:多表连接EXPLAINSELECTo.*,u.nameFROMorders oJOINusers uONo.user_id=u.id;-- orders 表 ref: const (若 user_id = 100)-- users 表 ref: db.o.user_id (引用 orders 表的 user_id)

3.2 rows:预估扫描行数

核心作用:MySQL 优化器预估需要读取的行数。值越小越好,但需注意:

  • 预估值:基于统计信息,可能不准确
  • 优化目标rows < 1000为佳,rows > 10000需警惕

统计信息更新

-- 当 rows 预估偏差大时,更新统计信息ANALYZETABLEorders;

实战案例

-- 慢查询:rows=980000SELECT*FROMordersWHEREuser_id=1000ANDstatus='shipped'ORDERBYcreate_timeDESCLIMIT10;-- EXPLAIN 分析:rows 过大,说明索引选择性差-- 优化:创建 (user_id, status, create_time) 复合索引

3.3 filtered:条件过滤率

含义:表示返回结果的行占扫描行数的百分比

-- 示例:扫描100行,返回10行,filtered=10%EXPLAINSELECT*FROMusersWHEREage>25ANDcity='Beijing';

优化意义filtered值低说明索引选择性差,需考虑:

  1. 更换索引列:将高选择性列放前面
  2. 覆盖索引:避免回表

四、Extra 字段:性能优化的"宝藏提示"

Extra 字段包含查询执行的额外信息,是性能诊断的关键线索。

4.1 高危信号:必须优化

Using filesort:无法使用索引排序,需额外排序操作

-- 触发场景:ORDER BY 非索引列或索引列顺序错误EXPLAINSELECT*FROMordersORDERBYamount;-- amount 无索引-- 优化:创建排序索引ALTERTABLEordersADDINDEXidx_create_time(create_time);EXPLAINSELECT*FROMordersORDERBYcreate_time;-- Extra: NULL

Using temporary:需创建临时表存储中间结果

-- 触发场景:DISTINCT、GROUP BY、ORDER BY 无索引EXPLAINSELECTDISTINCTuser_idFROMorders;-- 无索引EXPLAINSELECTstatus,COUNT(*)FROMordersGROUPBYstatus;-- status 无索引-- 优化:添加索引ALTERTABLEordersADDINDEXidx_status(status);

4.2 优化提示:建议改进

Using index:使用覆盖索引,无需回表

-- 理想状态EXPLAINSELECTuser_id,statusFROMordersWHEREuser_id=100;-- Extra: Using index (覆盖索引)

Using index condition:使用索引下推(ICP)

-- 复合索引 (name, age)EXPLAINSELECT*FROMusersWHEREnameLIKE'张%'ANDage=10;-- Extra: Using index condition (age 条件在存储引擎层过滤)

Using MRR:使用多范围读取优化

-- 范围查询EXPLAINSELECT*FROMordersWHEREuser_idBETWEEN100AND200;-- Extra: Using MRR (回表时顺序读取)

4.3 Extra 字段优化口诀

Extra 值含义优化动作
Using filesort文件排序添加排序索引
Using temporary临时表添加 GROUP BY/ORDER BY 索引
Using index覆盖索引保持现状,理想状态
Using index condition索引下推确认 ICP 开启
Using MRR多范围读取确认 MRR 开启
Using whereServer 层过滤考虑索引覆盖
NULL正常无需优化

五、optimizer_trace:优化器决策黑盒破解

5.1 什么是 optimizer_trace?

optimizer_trace是 MySQL 5.6 引入的优化器决策追踪工具,记录优化器如何选择执行计划的完整过程。它解决了 EXPLAIN 的局限性:

  • EXPLAIN 只展示最终选择的执行计划
  • optimizer_trace 展示为什么选这个计划(包括所有备选方案和成本计算)

5.2 开启与配置

会话级开启(推荐):

-- 开启 traceSEToptimizer_trace="enabled=on",end_markers_in_json=on;-- 执行需要分析的 SQLSELECT*FROMordersWHEREuser_id=100ANDstatus='shipped';-- 查看 trace 结果SELECT*FROMinformation_schema.optimizer_trace \G;

全局开启(慎用):

SETGLOBALoptimizer_trace="enabled=on",end_markers_in_json=on;

核心参数

-- 控制 trace 内存大小(默认 1MB)SEToptimizer_trace_max_mem_size=1048576;-- 限制返回的 trace 条数(默认 1)SEToptimizer_trace_limit=1;-- 控制跟踪内容(默认全部开启)SEToptimizer_trace_features='greedy_search=on,range_optimizer=on,dynamic_range=on';

5.3 trace 结构解析

trace 以 JSON 格式存储,包含 3 大阶段:

阶段 1:join_preparation(SQL 准备)
{"join_preparation":{"select#":1,"steps":[{"expanded_query":"/* select#1 */ select `orders`.`id` AS `id` ... from `orders` where ..."}]}}

作用:展示 SQL 重写后的标准格式,确认优化器接收到的查询。

阶段 2:join_optimization(核心优化阶段)

子阶段 2.1:condition_processing(条件处理)

{"condition_processing":{"condition":"WHERE","original_condition":"((`orders`.`user_id` = 100) AND (`orders`.`status` = 'shipped'))","steps":[{"transformation":"equality_propagation","resulting_condition":"(multiple equal(100, `orders`.`user_id`) ...)"}]}}

作用:展示条件重写过程(等值传播、常量传播)。

子阶段 2.2:rows_estimation(行数估算)

{"rows_estimation":[{"table":"`orders`","range_analysis":{"table_scan":{"rows":1000000,"cost":101000},"potential_range_indexes":[{"index":"idx_user_id","usable":true,"key_parts":["user_id"]}]}}]}

作用:对比全表扫描 vs 索引扫描的成本,揭示为什么选择某个索引

子阶段 2.3:considered_execution_plans(执行计划选择)

{"considered_execution_plans":[{"plan_prefix":[],"table":"`orders`","best_access_path":{"considered_access_paths":[{"access_type":"ref","index":"idx_user_id","rows":100,"cost":120.5,"chosen":true},{"access_type":"ALL","rows":1000000,"cost":101000,"chosen":false}]},"cost_for_plan":120.5,"rows_for_plan":100,"chosen":true}]}

作用:展示所有候选计划的成本对比,最终选择 cost 最小的计划

阶段 3:join_execution(执行阶段)
{"join_execution":{"select#":1,"steps":[]}}

5.4 实战案例:索引选择之谜

问题:为什么有时 MySQL 不选"最优"索引?

场景:表orders有索引idx_user_ididx_status,查询:

SELECT*FROMordersWHEREuser_id=100ANDstatus='shipped';

EXPLAIN 结果

-- 可能使用了 idx_status,而非 idx_user_idtype: refkey: idx_statusrows:5000

optimizer_trace 分析

-- 开启 traceSEToptimizer_trace="enabled=on";-- 执行查询SELECT*FROMordersWHEREuser_id=100ANDstatus='shipped';-- 查看 traceSELECT*FROMinformation_schema.optimizer_trace \G;

trace 关键信息

{"potential_range_indexes":[{"index":"idx_user_id","rows":100,// user_id=100 过滤后约 100 行"cost":150.0},{"index":"idx_status","rows":5000,// status='shipped' 过滤后约 5000 行"cost":120.0// 但 cost 更低!}]}

真相:优化器认为idx_statuscost 更低(可能因为 idx_user_id 的回表成本高),但实际idx_user_id更优。

解决方案

-- 方案1:强制使用索引SELECT*FROMordersFORCEINDEX(idx_user_id)WHEREuser_id=100ANDstatus='shipped';-- 方案2:创建复合索引ALTERTABLEordersADDINDEXidx_user_status(user_id,status);

六、慢SQL分析完整流程

6.1 四步诊断法

Step 1:识别慢SQL

-- 开启慢查询日志SETGLOBALslow_query_log='ON';SETGLOBALlong_query_time=1;-- 阈值1秒-- 查看慢SQL日志mysqldumpslow-s t/var/log/mysql/slow.log|head-20;

Step 2:EXPLAIN 初步分析

EXPLAINSELECT*FROMordersWHEREuser_id=100ANDstatus='shipped';-- 重点关注:type, key, rows, Extra

Step 3:optimizer_trace 深度追踪(当 EXPLAIN 无法解释时)

SEToptimizer_trace="enabled=on";-- 执行SQL-- 查看 trace,分析优化器决策

Step 4:针对性优化

  • 索引优化:添加/修改索引
  • SQL重写:避免函数、转换条件
  • 结构优化:分表分区
  • 参数调优:调整join_buffer_size,read_rnd_buffer_size

6.2 实战案例:从慢查询到优化

原始慢SQL

-- 执行时间:5秒SELECT*FROMordersWHEREDATE(create_time)='2024-01-01'ORDERBYidLIMIT10;

Step 1:EXPLAIN 分析

EXPLAINSELECT*FROMordersWHEREDATE(create_time)='2024-01-01'ORDERBYidLIMIT10;-- 结果:-- type: ALL(全表扫描)-- key: NULL(未使用索引)-- rows: 1000000-- Extra: Using where

问题定位

  • DATE(create_time)导致索引失效
  • ORDER BY id产生 filesort

Step 2:optimizer_trace 验证

-- 开启 traceSEToptimizer_trace="enabled=on";-- trace 显示:优化器放弃 idx_create_time 索引,因为函数操作"condition_processing": {"transformation":"func_date_conversion","index_unusable":true}

Step 3:优化方案

-- 优化后SQL(执行时间:50ms)SELECT*FROMordersWHEREcreate_time>='2024-01-01 00:00:00'ANDcreate_time<'2024-01-02 00:00:00'ORDERBYidLIMIT10;-- 添加复合索引ALTERTABLEordersADDINDEXidx_ctime_id(create_time,id);

Step 4:验证优化效果

EXPLAINSELECT*FROMordersWHEREcreate_time>='2024-01-01 00:00:00'ANDcreate_time<'2024-01-02 00:00:00'ORDERBYidLIMIT10;-- 结果:-- type: range-- key: idx_ctime_id-- rows: 100-- Extra: Using index condition-- 性能提升:5秒 → 50ms(100倍)

七、高级技巧与避坑指南

7.1 optimizer_trace 实战技巧

场景1:多个索引的选择困惑

-- 表有 idx_a, idx_b, idx_c,查询 WHERE a=1 AND b=2 AND c=3-- EXPLAIN 显示使用了 idx_c,但不确定为何不用 idx_ab-- 使用 trace 查看 cost 计算"considered_execution_plans":[{"access_type":"ref","index":"idx_ab","cost":200,"chosen":false},{"access_type":"ref","index":"idx_c","cost":150,"chosen":true}]

场景2:JOIN 顺序优化

-- 三表 JOIN,优化器选择了错误的驱动表-- trace 中查看 table_dependencies 和 considered_plans

7.2 常见误区

误区1:rows 越小越好

  • 真相:rows 是预估值,filtered列同样重要。可能扫描100行过滤出10行(filtered=10%),不一定比扫描500行过滤出400行(filtered=80%)更优。

误区2:有索引就一定会用

  • 真相:优化器基于 cost 决策,可能因回表成本高数据分布不均等原因放弃索引。此时需用FORCE INDEX或优化索引设计。

误区3:EXPLAIN 显示 Using index 就完美

  • 真相:需确认是否Using filesortUsing temporary,覆盖索引不能解决所有问题。

7.3 慢SQL优化口诀

索引失效三宗罪:函数计算、隐式转换、左模糊 排序优化两法宝:索引覆盖、最左前缀 连接查询要记牢:小表驱动、索引关联 trace 分析三步走:开启执行、查看 JSON、对比 cost

八、总结:从表象到本质的优化思维

工具作用适用场景输出价值
EXPLAIN执行计划快照日常快速诊断type/key/rows/Extra
optimizer_trace优化器决策过程索引选择异常、复杂查询成本计算、备选方案
慢查询日志性能监控定位慢SQL执行时间、扫描行数

核心方法论

  1. 先监控:通过慢日志定位慢SQL
  2. 再快照:用 EXPLAIN 获取执行计划
  3. 后追踪:用 optimizer_trace 破解决策黑盒
  4. 终验证:优化后重复分析,形成闭环

真正的性能优化不是"调参数",而是理解 MySQL 优化器的决策逻辑,让 SQL、索引、数据分布三者协同工作。掌握 EXPLAIN 和 optimizer_trace,就相当于拥有了慢SQL分析的"CT扫描仪"和"病理报告"。

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

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

相关文章

【紧急预案】容器大规模故障时,如何5分钟内自动恢复服务?

第一章&#xff1a;容器大规模故障的应急响应机制当 Kubernetes 集群中出现容器大规模崩溃或无法调度的情况时&#xff0c;快速响应与精准定位是恢复服务稳定的关键。建立标准化的应急响应流程&#xff0c;有助于在黄金时间内控制故障影响范围。故障识别与初步诊断 首先需通过监…

HunyuanVideo-Foley Docker部署:容器化运行的最佳配置

HunyuanVideo-Foley Docker部署&#xff1a;容器化运行的最佳配置 1. 引言 1.1 业务场景描述 随着短视频、影视后期和内容创作行业的快速发展&#xff0c;音效制作已成为提升视频质量的关键环节。传统音效添加依赖人工逐帧匹配&#xff0c;耗时耗力且专业门槛高。HunyuanVid…

奇奇视频 / 双子星动漫 / 挽离漫画:这三款工具太懂内容党

翻应用商店总怕碰着 “花架子” App&#xff0c;直到挖到奇奇视频、双子星动漫、挽离漫画这三个&#xff0c;试完直接清了手机里一半冗余软件。 奇奇视频是刷剧党的 “精准货架”。界面没多余弹窗&#xff0c;按 “剧 / 影 / 漫” 分类&#xff0c;新剧标着 “更新至 XX 集”&a…

Webtoon漫画批量下载完整教程:一键保存所有章节的终极方案

Webtoon漫画批量下载完整教程&#xff1a;一键保存所有章节的终极方案 【免费下载链接】Webtoon-Downloader Webtoons Scraper able to download all chapters of any series wanted. 项目地址: https://gitcode.com/gh_mirrors/we/Webtoon-Downloader 想要永久收藏喜爱…

JLink驱动安装方法:Windows系统完整指南

JLink驱动安装全攻略&#xff1a;从零开始搭建稳定调试环境 你有没有遇到过这样的情况&#xff1f;刚拿到一块新的开发板&#xff0c;满怀期待地插上J-Link调试器&#xff0c;打开Keil或STM32CubeIDE&#xff0c;结果却弹出“Cannot connect to J-Link”——设备根本识别不了。…

AnimeGANv2优化技巧:解决动漫化后背景失真的问题

AnimeGANv2优化技巧&#xff1a;解决动漫化后背景失真的问题 1. 背景与问题定义 随着深度学习在图像风格迁移领域的快速发展&#xff0c;AnimeGANv2 成为最受欢迎的照片转二次元模型之一。其核心优势在于轻量级架构和对人脸特征的高度保留&#xff0c;尤其适用于将真实人像转…

隐私计算新选择:本地数据+云端模型,原始数据不出域

隐私计算新选择&#xff1a;本地数据云端模型&#xff0c;原始数据不出域 1. 医疗AI的隐私困境与解决方案 医院每天产生大量病例数据&#xff0c;这些数据对AI模型训练和诊断辅助极具价值。但医疗数据包含患者隐私信息&#xff0c;直接上传到云端存在泄露风险。传统做法往往面…

元宇宙建筑工必看:Holistic Tracking实现低成本3D空间扫描

元宇宙建筑工必看&#xff1a;Holistic Tracking实现低成本3D空间扫描 1. 为什么你需要了解Holistic Tracking&#xff1f; 想象一下&#xff0c;你是一位独立游戏开发者&#xff0c;想要在元宇宙中还原自家老宅作为游戏场景。传统激光扫描仪日租金高达3000元&#xff0c;而A…

办公效率翻倍:AI智能文档扫描仪使用全攻略

办公效率翻倍&#xff1a;AI智能文档扫描仪使用全攻略 1. 引言&#xff1a;为什么你需要一个本地化智能扫描工具 在数字化办公日益普及的今天&#xff0c;将纸质文档快速、清晰地转化为电子文件已成为日常刚需。无论是合同签署、发票归档&#xff0c;还是课堂笔记、白板记录&…

拒绝浪费:GPU云服务按秒计费实操手册

拒绝浪费&#xff1a;GPU云服务按秒计费实操手册 1. 为什么你需要按秒计费&#xff1f; 作为算法工程师&#xff0c;你可能经常遇到这样的场景&#xff1a;花大价钱包月租用GPU服务器&#xff0c;结果70%的时间机器都在闲置。按传统包月方式&#xff0c;每月白白浪费上千元成…

Holistic Tracking模型压缩实战:云端剪枝量化,速度提升5倍

Holistic Tracking模型压缩实战&#xff1a;云端剪枝量化&#xff0c;速度提升5倍 引言 在急诊科这样的关键医疗场景中&#xff0c;每秒钟都可能关乎生死。想象一下&#xff0c;当医生需要AI系统快速分析患者CT影像时&#xff0c;如果模型响应需要3秒钟&#xff0c;这等待时间…

AI绘画接单指南:Stable Diffusion云端高效工作流

AI绘画接单指南&#xff1a;Stable Diffusion云端高效工作流 1. 为什么插画师需要云端AI绘画方案&#xff1f; 作为一名插画师&#xff0c;你是否遇到过这些困扰&#xff1a; - 客户临时加急需求&#xff0c;但本地电脑渲染一张高清图要10分钟 - 同时接多个订单时&#xff0c…

HunyuanVideo-Foley用户体验:创作者真实反馈汇总分析

HunyuanVideo-Foley用户体验&#xff1a;创作者真实反馈汇总分析 1. 背景与技术定位 随着短视频、影视后期和互动内容的爆发式增长&#xff0c;音效制作逐渐成为内容创作中不可忽视的一环。传统音效添加依赖专业音频库和人工匹配&#xff0c;耗时长、成本高&#xff0c;且对非…

AD画PCB从零实现:创建第一个工程项目

从零开始用AD画PCB&#xff1a;我的第一个工程实战手记作为一个刚入门电子设计的“小白”&#xff0c;你有没有过这样的经历&#xff1f;打开Altium Designer&#xff0c;满屏图标眼花缭乱&#xff0c;不知道该点哪里&#xff1b;想画个简单的电路板&#xff0c;结果发现原理图…

【跨架构镜像构建终极指南】:掌握多平台Docker镜像一键生成核心技术

第一章&#xff1a;跨架构镜像构建概述在现代容器化开发与部署中&#xff0c;跨架构镜像构建成为支持多平台&#xff08;如 x86_64、ARM64&#xff09;应用分发的关键技术。传统的镜像构建通常依赖于本地运行环境的 CPU 架构&#xff0c;导致无法直接为不同硬件平台生成兼容的镜…

免费全平台!Koodo-Reader,电子书党必备轻量阅读器

谁懂啊&#xff01;找个干净无广告的电子书阅读器&#xff0c;不是捆绑一堆插件&#xff0c;就是只支持单一系统&#xff0c;真的太难了&#xff01; 下载地址&#xff1a;https://pan.quark.cn/s/fa351f755b86 备用地址&#xff1a;https://pan.baidu.com/s/1pRTU5SCBrcThoL…

3种你必须掌握的跨架构镜像构建方法:告别重复打包时代

第一章&#xff1a;跨架构镜像构建的时代背景与挑战随着云计算、边缘计算和物联网的快速发展&#xff0c;异构硬件环境成为常态。开发者不仅需要在 x86_64 架构上部署应用&#xff0c;还需支持 ARM、RISC-V 等多种处理器架构。这催生了对跨架构镜像构建的迫切需求&#xff0c;尤…

容器网络隔离技术选型指南(CNI插件对比与实战建议)

第一章&#xff1a;容器网络隔离的核心挑战在现代云原生架构中&#xff0c;容器化技术的广泛应用带来了高效资源利用与快速部署的优势&#xff0c;但同时也引入了复杂的网络隔离问题。多个容器共享宿主机内核和网络栈&#xff0c;若缺乏有效的隔离机制&#xff0c;可能导致服务…

VibeVoice-TTS推理速度慢?批处理优化实战教程

VibeVoice-TTS推理速度慢&#xff1f;批处理优化实战教程 1. 引言&#xff1a;从网页交互到工程优化的跨越 随着大模型在语音合成领域的深入应用&#xff0c;VibeVoice-TTS作为微软推出的高性能多说话人对话式文本转语音&#xff08;TTS&#xff09;框架&#xff0c;凭借其支…