mysql in查询速度慢,试试改用join

本文探讨了一种SQL查询优化策略,通过将原本使用的IN子查询替换为LEFTJOIN,显著提升了查询速度。在项目中,对zt_proj_invoice_req表的查询由IN操作改为了LEFTJOIN,结合内部查询优化,减少了数据处理时间,从而提高了整体查询效率。这种方法对于大数据量的数据库操作尤其有益,是数据库性能调优的一个实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是在一个项目中遇到的问题,项目原来的代码使用了in进行查询,速度非常慢,后面我使用left join之后速度得到很大的提升

修改前:

SELECT
	`c`.*,
	pir_total_amount,
CASE
		
		WHEN pci.count IS NULL THEN
		0 ELSE pci.count 
	END AS contract_count 
FROM
	zt_contract_info c
	LEFT JOIN ( SELECT contract_id, count( 1 ) AS count FROM zt_proj_contract_info zpci WHERE zpci.del = 0 GROUP BY contract_id ) pci ON `pci`.`contract_id` = `c`.`id`
	LEFT JOIN (
	SELECT
		pci.contract_id,
		sum( pir.total_amount ) AS pir_total_amount 
	FROM
		zt_proj_contract_info pci
		//这里使用了in进行查询
		LEFT JOIN zt_proj_invoice_req pir ON pir.del = 0 
		AND pir.parent_id IN (
		SELECT
			max( pf.id ) AS id 
		FROM
			zt_proj_form_info pf 
		WHERE
			pf.pid = pci.pid 
			AND form_id = 14 
			AND pf.del = 0 
			AND pf.stage = 99 
		) 
		//==============
	WHERE
		pci.del = 0 
	GROUP BY
		pci.contract_id 
	) sum_pir ON `sum_pir`.`contract_id` = `c`.`id` 
WHERE
	`c`.`del` = 0 
	AND ( c.del = 0 AND c.confirm_amount != sum_pir.pir_total_amount OR sum_pir.pir_total_amount IS NULL ) 
ORDER BY
	`c`.`id`

修改后:


	SELECT
		`c`.*,
		pir_total_amount,
	CASE
			
			WHEN pci.count IS NULL THEN
			0 ELSE pci.count 
		END AS contract_count 
	FROM
		zt_contract_info c
		LEFT JOIN ( SELECT contract_id, count( 1 ) AS count FROM zt_proj_contract_info zpci WHERE zpci.del = 0 GROUP BY contract_id ) pci ON `pci`.`contract_id` = `c`.`id`
		LEFT JOIN (
		SELECT
			pci.contract_id,
			sum( maxpir.total_amount ) AS pir_total_amount 
		FROM
			zt_proj_contract_info pci
			//改为LEFT JOIN进行查询
			LEFT JOIN (
			SELECT * FROM
				zt_proj_invoice_req pir
				LEFT JOIN (
				SELECT
					pf.pid,
					pf.id AS pfid 
				FROM
					zt_proj_form_info pf 
				WHERE
					form_id = 14 
					AND pf.del = 0 
					AND pf.stage = 99 
				) maxpf ON maxpf.pfid = pir.parent_id 
				AND pir.del = 0 
			) AS maxpir ON maxpir.pid = pci.pid 
			//==============
		WHERE
			pci.del = 0 
		GROUP BY
			pci.contract_id 
		) sum_pir ON `sum_pir`.`contract_id` = `c`.`id` 
	WHERE
		`c`.`del` = 0 
		AND ( c.del = 0 AND c.confirm_amount != sum_pir.pir_total_amount OR sum_pir.pir_total_amount IS NULL ) 
ORDER BY
	`c`.`id`

通过explain可以看出前后的差距

修改前:
在这里插入图片描述

修改后:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值