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

带JOIN与WHERE语句的COUNT慢查询性能优化咨询

优化COUNT查询的方案

针对这条耗时1.33秒的关联统计查询,结合你的表数据量和结构,可通过以下方式优化:

1. 创建针对性复合索引

给tickets表添加复合索引

CREATE INDEX idx_tickets_createdat_orderid ON tickets(created_at, order_id);

这个索引能直接过滤出created_at > '2023-01-01'的记录,同时直接获取关联需要的order_id字段,避免回表查询整张tickets表的数据,大幅减少数据扫描量。

给orders表添加复合索引

CREATE INDEX idx_orders_status_id ON orders(status, id);

查询需要过滤status = 'paid'的订单,同时用id关联tickets表,这个复合索引可以快速定位所有符合状态的订单ID,避免全表扫描orders。

2. 清理冗余索引

观察你的tickets表建表语句,tickets_order_id_foreign和tickets_order_id_index都是针对order_id的单字段索引,功能完全重复。保留其中一个即可,比如删除冗余的那一个:

DROP INDEX tickets_order_id_index ON tickets;

冗余索引会增加数据插入、更新时的维护成本,清理后能间接提升查询效率。

3. 验证执行计划

执行EXPLAIN命令查看查询的执行逻辑,确认索引是否被正确使用:

EXPLAIN
SELECT COUNT(*) AS aggregate
FROM `tickets`
INNER JOIN `orders` ON `orders`.`id` = `tickets`.`order_id`
WHERE `orders`.`status` = 'paid' AND `tickets`.`created_at` > '2023-01-01 00:00:00';

重点看type列(理想值为range或ref)、key列(应显示我们创建的复合索引)、rows列(预估扫描行数应远小于全表数据量)。

4. 微调查询写法(可选)

调整关联顺序,让优化器优先处理过滤条件更严格的表(如果paid状态的订单占比远小于tickets表中符合时间条件的记录):

SELECT COUNT(*) AS aggregate
FROM orders o
INNER JOIN tickets t ON t.order_id = o.id
WHERE o.status = 'paid' AND t.created_at > '2023-01-01 00:00:00';

不过在索引配置合理的情况下,数据库优化器通常会自动选择最优关联顺序,这个调整的收益可能有限。

内容的提问来源于stack exchange,提问作者sweebee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:05:23