Muh*_*eel 2 mysql optimization group-by subquery
我有这个查询,这是一个依赖查询,需要很长的执行时间
SELECT
u.id,
u.user_name,
ifnull((select longitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
ifnull((select latitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
(select created from map where user_id = 1 order by created desc limit 1) as LatestTime
FROM users as u
WHERE id IN(SELECT
user1_id FROM relation
WHERE users.id = 1)
ORDER BY id;
Run Code Online (Sandbox Code Playgroud)
我试过(依赖)这个查询
SELECT
u.id,
u.user_name,
m.map_id,
m.longitude,
m.latitude,
m.Date as created
FROM users as u
left join (select
map_id,
longitude,
latitude,
user_id,
max(created) as `Date`
from map
group by user_id) as m
on m.user_id = u.id
WHERE id IN(SELECT
user1_id FROM relation
WHERE users.id = 1)
ORDER BY id;
Run Code Online (Sandbox Code Playgroud)
问题是第一个查询依赖并且工作正常,但需要很长的执行时间.对于第二个查询,问题是它没有获取最新创建的时间.现在我想优化这个查询.主题是在子查询中我首先创建组,然后我试图获得每组的最后记录.这是表格结构.
users : id , user_name
map : map_id , user_id ,longitude , latitude, created
relations : id , user1_id , user2_id , relation
Run Code Online (Sandbox Code Playgroud)
在需要性能的地方,SELECT
子句中的子查询确实很痛苦,必须放逐:)
你可以重写这个部分:
SELECT
u.id,
u.user_name,
ifnull((select longitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
ifnull((select latitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
(select created from map where user_id = 1 order by created desc limit 1) as LatestTime
FROM users as u
Run Code Online (Sandbox Code Playgroud)
在:
SELECT
u.id,
u.user_name,
COALESCE(m1.longitude, 0) as longitude,
COALESCE(m1.latitude, 0) as latitude
FROM users u
LEFT JOIN map m1 ON m1.user_id = u.id
LEFT JOIN map m2 ON m2.user_id = m1.user_id AND m2.map_id > m1.map_id
WHERE m2.map_id IS NULL
Run Code Online (Sandbox Code Playgroud)
我在这个答案中写了一个简短的查询结构解释.这是一个非常好的技巧,因为它更具可读性,无子查询和更高性能.
我还没有看过这个IN
部分,但如果上面没有帮助的话.
Edit1:您可以提取创建的日期并使用MAX()代替.
SELECT
u.id,
u.user_name,
COALESCE(m1.longitude, 0) as longitude,
COALESCE(m1.latitude, 0) as latitude,
created.LatestTime
FROM (SELECT MAX(created) FROM map WHERE user_id = 1) created
INNER JOIN users u ON TRUE
LEFT JOIN map m1 ON m1.user_id = u.id
LEFT JOIN map m2 ON m2.user_id = m1.user_id AND m2.map_id > m1.map_id
WHERE m2.map_id IS NULL
Run Code Online (Sandbox Code Playgroud)