You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCP MySQL高并发场景下分页计数查询性能急剧下降问题排查求助

GCP MySQL高并发场景下分页计数查询性能急剧下降问题排查求助

大家好,我们团队最近在GCP MySQL上遇到了一个特别头疼的性能问题,折腾了好几天都没摸到根因,想请各位大佬帮忙分析下!

问题背景

我们的数据库是GCP上的MySQL实例,最初配置是4核16G SSD,整个实例总数据量大概50G,但核心业务库只有15G。问题出在白天用户访问高峰时段:大部分页面加载慢到离谱,甚至有页面要40秒以上才能打开。

更诡异的是,单独执行那些慢查询(比如分页用的count统计),耗时也就500ms左右,但一上并发直接雪崩:

  • 5个并发查询:平均耗时3秒
  • 10个并发:平均7秒
  • 20个并发:直接冲到30秒以上...

已做的尝试&优化

  1. 索引优化:把能加的索引都加了——单字段索引(issue_date、customer_id、status、workflow每个字段单独加)、复合索引(customer_id+status+workflow+issue_date)都试过。优化后耗时能砍到原来的1/2甚至1/3,但只是把问题往后推了推,高并发下还是炸。
  2. 资源升级测试:后来临时升级到8核32G,并发表现确实好些——100个并发平均1.5秒,200个并发平均3秒,但总觉得这只是堆资源的“治标”办法,不仅成本更高,而且根本没解决性能雪崩的根源问题。
  3. 其他尝试:试过加读锁,完全没用;也考虑过预存统计结果,但因为查询里的每个过滤条件都是用户实时输入的,根本没法预存。

典型问题查询示例

下面是一个用来做分页的count查询(已经是我们优化到最简的版本了),单独跑大概150ms,但一并发就拖垮整个库:

select count(i1_0.id) 
from invoice i1_0 
where i1_0.issue_date BETWEEN '2025-01-01' and '2025-07-30' 
and (i1_0.customer_id = 20 
and (i1_0.status, i1_0.workflow) in ((1,1), (2,1), (3,1), (4,1), (5,1), (6,1), (7,1)) );
  • 表总数据量大概400万条,这个查询返回的计数是7万左右
  • 字段类型:issue_date是DATE,customer_id是BIGINT,status和workflow是INTEGER
  • 所有过滤条件都是用户实时输入,没法预存结果

EXPLAIN执行计划

我们跑了这个查询的EXPLAIN,结果如下:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEi1_0rangeinvoice_issue_date_IDX,invoice_customer_id_IDX,invoice_workflow_num_IDX,invoice_status_num_IDX,composite_idxcomposite_idx23145523100Using where; Using index

表结构(简化版)

下面是invoice表的完整结构(原输入最后有截断,已省略):

CREATE TABLE `invoice` (
 `id` bigint NOT NULL AUTO_INCREMENT,
 `invoice_type_code` varchar(10) NOT NULL COMMENT '',
 `issue_date` date DEFAULT NULL,
 `category_code` varchar(3) DEFAULT NULL COMMENT '',
 `document_currency_code` varchar(3) DEFAULT NULL COMMENT '',
 `tax_exclusive_amount` decimal(19,6) DEFAULT NULL COMMENT '',
 `tax_inclusive_amount` decimal(19,6) DEFAULT NULL COMMENT '',
 `payable_amount` decimal(19,6) DEFAULT NULL COMMENT '',
 `payment_means_code` varchar(11) DEFAULT NULL COMMENT '',
 `datecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
 `dateupdated` timestamp NULL DEFAULT NULL,
 `tax_amount` decimal(19,6) DEFAULT NULL COMMENT '',
 `percent` decimal(19,1) DEFAULT NULL,
 `supplier_id` bigint DEFAULT NULL,
 `customer_id` bigint DEFAULT NULL,
 `downloaded` bit(1) DEFAULT NULL COMMENT '',
 `status_date` datetime DEFAULT NULL COMMENT '',
 `submission_type` varchar(100) DEFAULT NULL COMMENT '',
 `tax_type` varchar(100) DEFAULT NULL COMMENT '',
 `market_number` varchar(100) DEFAULT NULL COMMENT '',
 `obligation_number` varchar(50) DEFAULT NULL,
 `comment_status` varchar(2000) DEFAULT NULL,
 `invoice_number` varchar(20) NOT NULL COMMENT '',
 `flux_id` bigint DEFAULT NULL,
 `supplier_service` varchar(100) DEFAULT NULL,
 `customer_service` varchar(100) DEFAULT NULL,
 `metadata` longtext NOT NULL COMMENT '',
 `due_date` date DEFAULT NULL COMMENT '',
 `iban` varchar(34) DEFAULT NULL COMMENT '',
 `department_id` bigint DEFAULT NULL,
 `origin_number` varchar(20) DEFAULT NULL,
 `supplier_auxiliary_code` varchar(100) DEFAULT NULL COMMENT '',
 `supplier_type` varchar(100) DEFAULT NULL COMMENT '',
 `supplier_type_code` varchar(100) DEFAULT NULL COMMENT '',
 `accounting_date` date DEFAULT NULL COMMENT '',
 `custom_info` varchar(500) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

疑问&求助

我们团队没有专职DBA,现在完全摸不着头脑:

  • 为什么单独查询性能尚可,一并发就雪崩?
  • 除了堆资源和加索引,还有什么排查方向?比如锁机制、MySQL配置、或者查询本身还有隐藏的优化点?
  • 会不会是InnoDB的某些默认配置不适合高并发场景?

麻烦各位大佬给点思路,谢谢啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 09:38:01