1. 程式人生 > >mysql多個left join

mysql多個left join

mysql查詢時需要連線多個表時,比如查詢訂單的商品表,需要查詢商品的其他資訊,其他資訊不在訂單的商品表,需要連線其他庫的表,但是連線的條件基本都是商品ID就可以了,先給一個錯誤語句(查詢之間的巢狀,效率很低):

SELECT
	A.order_id,
	A.wid,
	A.work_name,
	A.supply_price,
	A.sell_price,
	A.total_num,
	A.sell_profit,
	A.sell_percent,
	A.goods_id,
	A.goods_name,
	A.classify,
	B.gb_name
FROM
	(
		SELECT
			A.sub_order_id AS order_id,
			A.photo_id AS wid,
			A.photo_name AS work_name,
			A.supply_price,
			A.sell_price,
			sum(A.num) AS total_num,
			(
				A.sell_price - A.supply_price
			) AS sell_profit,
			(
				A.sell_price - A.supply_price
			) / A.sell_price AS sell_percent,
			A.goods_id,
			A.goods_name,
			B.goods_name AS classify
		FROM
			order_goods AS A
		LEFT JOIN (
			SELECT
				A.goods_id,
				A.parentid,
				B.goods_name
			FROM
				test_qyg_goods.goods AS A
			LEFT JOIN test_qyg_goods.goods AS B ON A.parentid = B.goods_id
		) AS B ON A.goods_id = B.goods_id
		WHERE
			A.createtime >= '2016-09-09 00:00:00'
		AND A.createtime <= '2016-10-16 23:59:59'
		AND FROM_UNIXTIME(
			UNIX_TIMESTAMP(A.createtime),
			'%Y-%m-%d'
		) != '2016-09-28'
		AND FROM_UNIXTIME(
			UNIX_TIMESTAMP(A.createtime),
			'%Y-%m-%d'
		) != '2016-10-07'
		GROUP BY
			A.photo_id
		ORDER BY
			A.goods_id ASC
	) AS A
LEFT JOIN (
	SELECT
		A.wid,
		A.brand_id,
		B.gb_name
	FROM
		test_qyg_user.buser_goods_list AS A
	LEFT JOIN test_qyg_supplier.brands AS B ON A.brand_id = B.gbid
) AS B ON A.wid = B.wid
查詢結果耗時4秒多,explain分析,發現其中2個子查詢是全部掃描,可以使用mysql的多個left join優化
SELECT
	A.sub_order_id,
	A.photo_id AS wid,
	A.photo_name AS work_name,
	A.supply_price,
	A.sell_price,
	sum(A.num) AS total_num,
	(
		A.sell_price - A.supply_price
	) AS sell_profit,
	(
		A.sell_price - A.supply_price
	) / A.sell_price AS sell_percent,
	A.goods_id,
	A.goods_name,
	B.parentid,
	C.goods_name AS classify,
	D.brand_id,
	E.gb_name,
	sum(
		CASE
		WHEN F.buy_type = 'yes' THEN
			A.num
		ELSE
			0
		END
	) AS total_buy_num,
	sum(
		CASE
		WHEN F.buy_type = 'yes' THEN
			A.num
		ELSE
			0
		END * A.sell_price
	) AS total_buy_money,
	sum(
		CASE
		WHEN F.buy_type = 'no' THEN
			A.num
		ELSE
			0
		END
	) AS total_give_num,
	sum(
		CASE
		WHEN F.buy_type = 'no' THEN
			A.num
		ELSE
			0
		END * A.sell_price
	) AS total_give_money
FROM
	order_goods AS A
LEFT JOIN test_qyg_goods.goods AS B ON A.goods_id = B.goods_id
LEFT JOIN test_qyg_goods.goods AS C ON B.parentid = C.goods_id
LEFT JOIN test_qyg_user.buser_goods_list AS D ON A.photo_id = D.wid
LEFT JOIN test_qyg_supplier.brands AS E ON D.brand_id = E.gbid
LEFT JOIN order_info_sub AS F ON A.sub_order_id = F.order_id
WHERE
	A.createtime >= '2016-09-09 00:00:00'
AND A.createtime <= '2016-10-16 23:59:59'
AND FROM_UNIXTIME(
	UNIX_TIMESTAMP(A.createtime),
	'%Y-%m-%d'
) != '2016-09-28'
AND FROM_UNIXTIME(
	UNIX_TIMESTAMP(A.createtime),
	'%Y-%m-%d'
) != '2016-10-07'
GROUP BY
	A.photo_id
ORDER BY
	A.goods_id ASC

查詢結果耗時0.04秒