Mysql query tuning

the following SQL, query is very slow to optimize

SELECT DISTINCT member.loginName,member.memberLevelId,member.regTime,member.multipleChannelsId,
(SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id) AS "",
(SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) AS "",
(SELECT SUM(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) AS "",
(SELECT MAX(OrderCreateTime) FROM cs_order WHERE MemberID = member.id) AS ""
FROM cs_member member JOIN cs_order o ON member.id = o.MemberId 
JOIN cs_order_promotion_log op ON o.id = op.orderId
JOIN cs_coupon_definition cd ON op.PromotionID = cd.PromotionId
JOIN cs_coupon_batch cb ON cd.id = cb.CouponDefinitionId
JOIN cs_order_item oi ON o.id = oi.OrderId
JOIN cs_product p ON oi.ProductId = p.id
WHERE TRUE
AND (SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) > "10"
AND (SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) < "50"
AND (SELECT COUNT(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) > "1000"
AND (SELECT COUNT(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) < "10000"
LIMIT 20;

the actual SQL of the business is like this.

SELECT DISTINCT member.loginName,member.memberLevelId,member.regTime,member.multipleChannelsId,
(SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id) AS "",
(SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) AS "",
(SELECT SUM(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) AS "",
(SELECT MAX(OrderCreateTime) FROM cs_order WHERE MemberID = member.id) AS ""
FROM cs_member member JOIN cs_order o ON member.id = o.MemberId 
JOIN cs_order_promotion_log op ON o.id = op.orderId
JOIN cs_coupon_definition cd ON op.PromotionID = cd.PromotionId
JOIN cs_coupon_batch cb ON cd.id = cb.CouponDefinitionId
JOIN cs_order_item oi ON o.id = oi.OrderId
JOIN cs_product p ON oi.ProductId = p.id
WHERE member.loginName LIKE "%loginName%" 
OR member.mobile LIKE "%mobile%" 
OR member.email LIKE "%email%" 
AND member.memberLevelId = ""
AND member.cityId = ""
AND member.multipleChannelsId = ""
AND member.regLanguageType = ""
AND member.regTime > ""
AND member.regTime < ""
AND o.OrderCreateTime > ""
AND o.OrderCreateTime > ""
AND p.CategoryId IN ("Id")
AND p.code IN ("")
AND p.code = ""
AND cb.ShortNum = ""
AND (SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) > ""
AND (SELECT COUNT(1) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) < ""
AND (SELECT COUNT(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) > ""
AND (SELECT COUNT(GoodsAmount) FROM cs_order WHERE MemberID = member.id AND OrderStatus >= 3 AND OrderStatus <= 5) < ""
Apr.26,2021

I just see a few subqueries and I know that slow is normal


  1. your last few and queries, "minimum number of orders issued, maximum number of orders issued, total amount of orders issued". If this is really the case with your needs, you can consider adding a few fields in cs_member for storage, and then update these fields when the data changes. In this way, the query speed will be much faster
  2. .
  3. check whether the index of the field associated with the table has been established, and if not, create the relevant index
  4. query field "Total number of orders issued, total amount of payment orders, total amount of payment orders, last order time", do not query here, wait for the specified number of data needed to find out, and then traverse the query, which will be much faster.
Menu