概述
MySQL使用group by的时候,经常会Using temporary; Using filesort
,这将导致查询速度很慢
表ddl如下所示,有50多万条:
CREATE TABLE `erp_storage_flow_log_report` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
`factory_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '工厂id',
`material_sku_depot_unique_index` varchar(50) NOT NULL DEFAULT '' COMMENT '物料仓库唯一索引',
`material_inbound_amount` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '料件入库',
`deleted_at` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `factory_id` (`factory_id`),
KEY `material_sku_depot_unique_index` (`material_sku_depot_unique_index`) USING BTREE,
KEY `deleted_at` (`deleted_at`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=512683 DEFAULT CHARSET=utf8mb4 COMMENT='出入库报表';
使用如下sql进行查询,查询时间很久:
SELECT
`storageSummaryReport` .*,
SUM(material_inbound_amount) AS `sum_material_inbound_amount`
FROM
`erp_storage_flow_log_report` `storageSummaryReport`
WHERE
(
`storageSummaryReport`.`factory_id` = 1
)
AND `storageSummaryReport`.`deleted_at` = 0
GROUP BY
`material_sku_depot_unique_index`
ORDER BY
`storageSummaryReport`.`id` DESC
LIMIT 0,
10
分析原因:
- 因为数据表中的factory_id都为1,deleted_at都等0,所以这两个where条件会导致几乎要遍历所有的数据,这个会导致很慢。
- 在group by 中使用order by,会导致file sort,这个也会导致速度很慢,既然它默认会排序,我们不给它排是不是就行啦。
- 我们一起来想下,执行group by语句为什么需要临时表呢?group by的语义逻辑,就是统计不同的值出现的个数。如果这个这些值一开始就是有序的,我们是不是直接往下扫描统计就好了,就不用临时表来记录并统计结果了
- group by列加索引是必然需要的
解决办法
- 去掉无实际意义的筛选条件
- 去掉order by语句
评论 (0)