1

我一个月前在一个网站上建立了一个查询。它工作正常。但是一个月后我被告知该网站加载页面变得非常缓慢。

当我搜索问题时,我发现我的查询执行速度非常慢,无法从 mysql 数据库中获取数据。然后我检查数据库,发现我通过连接使用的 4 个表分别有大约 216850、167634、64000、931 行。

我已经为这些表编制了索引。所以,我缺乏的地方。请帮助各位。

[编辑]

Table1: user_alert
Records: 216850
DB Type: InnoDB
Indexes: id(primary)

Table2: orders
Records: 167634
DB Type: InnoDB
Indexes: id(primary), order_id, customer_id

Table3: user_registration
Records: 64000 around
DB Type: InnoDB
Indexes: id(primary), email_address

Table4: cities
Records: 931
DB Type: InnoDB
Indexes: id(primary)

询问:

SELECT uas.alert_id, uas.user_id, uas.status, ur.first_name, ur.last_name, ur.email_address, o.order_id,
CASE WHEN ct.city_name IS NULL THEN uas.city_name ELSE ct.city_name END AS city_name
FROM `user_alert` uas
LEFT JOIN orders o ON o.customer_id = uas.user_id
LEFT JOIN user_registration ur ON ur.id = uas.user_id
LEFT JOIN `cities` ct ON ct.city_id = uas.city_id
WHERE uas.status = '1'
GROUP BY uas.user_id
ORDER BY uas.create_date DESC
4

1 回答 1

0

GROUP BY 用于向上聚合值。例如,如果您想要一个用户的订单计数,您可以使用 COUNT(o.order_id).....GROUP BY uas.user_id。每个用户有多个订单,但聚合函数只是在这里计算它们。但是,如果您在 GROUP BY uas.user_id 时仅选择 o.order_id,则它不知道为该用户 ID 返回可能的多个 order_id 值中的哪一个。

在这种情况下,它可能无关紧要,因为看起来订单表是唯一一个每次使用多行的表。如果你想要最新的,你可以使用 MAX(o.order_id) (假设 order_id 被分配为 order)。但是,如果您想要订单价值,则变得更加困难。

SELECT uas.alert_id, uas.user_id, uas.status, ur.first_name, ur.last_name, ur.email_address, MAX(o.order_id) AS LatestOrderId,
IFNULL(ct.city_name, uas.city_name) AS city_name
FROM `user_alert` uas
LEFT JOIN orders o ON o.customer_id = uas.user_id
LEFT JOIN user_registration ur ON ur.id = uas.user_id
LEFT JOIN `cities` ct ON ct.city_id = uas.city_id
WHERE uas.status = '1'
GROUP BY uas.user_id
ORDER BY uas.create_date DESC

如果您想要最新订单的(比如说)价值,那么它变得更加困难。

SELECT uas.alert_id, uas.user_id, uas.status, ur.first_name, ur.last_name, ur.email_address, Sub1.MaxOrderId AS LatestOrderId, o.order_value
IFNULL(ct.city_name, uas.city_name) AS city_name
FROM `user_alert` uas
LEFT JOIN (SELECT customer_id, MAX(order_id) AS MaxOrderId FROM orders GROUP BY customer_id) Sub1 ON Sub1.customer_id = uas.user_id
LEFT OUTER JOIN orders o ON o.customer_id = Sub1.user_id AND o.order_id = Sub1.MaxOrderId
LEFT JOIN user_registration ur ON ur.id = uas.user_id
LEFT JOIN `cities` ct ON ct.city_id = uas.city_id
WHERE uas.status = '1'
ORDER BY uas.create_date DESC

或者做一些基于 GROUP_CONCAT 的小提琴

SELECT uas.alert_id, uas.user_id, uas.status, ur.first_name, ur.last_name, ur.email_address, 
SUBSTRING_INDEX(GROUP_CONCAT(o.order_id ORDER BY o.order_id DESC), ',', 1) AS LatestOrderId, 
SUBSTRING_INDEX(GROUP_CONCAT(o.order_value ORDER BY o.order_id DESC), ',', 1) AS LatestOrderValue, 
IFNULL(ct.city_name, uas.city_name) AS city_name
FROM `user_alert` uas
LEFT OUTER JOIN orders o ON o.customer_id = uas.user_id AND o.order_id = Sub1.MaxOrderId
LEFT JOIN user_registration ur ON ur.id = uas.user_id
LEFT JOIN `cities` ct ON ct.city_id = uas.city_id
WHERE uas.status = '1'
GROUP BY uas.user_id
ORDER BY uas.create_date DESC
于 2013-11-08T13:45:21.147 回答