如何优化此查询并提高其性能,
SELECT user.id,user.name,profile.info,score.amount
FROM user
LEFT JOIN profile ON profile.user_id = user.id AND profile.type = 'language'
LEFT JOIN score ON score.user_id = user.id AND score.type = 'total'
WHERE email = 'example@mail.com'
返回结果:
[id] => 1060225
[name] => john
[info] => En
[ammount] => 533
返回结果2:
[id] => 1022805
[name] => karin
[info] =>
[ammount] => 11
表:
用户表
id name email
1 john example@mail.com
2 karin tt@kkk.com
3 Tom kk@yahoo.com
4 kit mm@gmail.com
个人资料表
id user_id type info
1 1 is_admin true
2 1 language En
3 1 active true
4 2 is_admin false
1 1 like null
2 2 favorite null
3 3 is_admin false
4 2 experience 4
得分表
id user_id type amount
1 1 daily 33
2 1 total 533
3 2 total 11
4 3 daily 44
感谢,
答案 0 :(得分:2)
对于此查询:
SELECT u.id, u.name, p.info, s.amount
FROM user u LEFT JOIN
profile p
ON p.user_id = u.id AND p.type = 'language' LEFT JOIN
score s
ON s.user_id = u.id AND s.type = 'total'
WHERE u.email = 'example@mail.com';
(我刚刚添加了表别名,以使查询更具可读性,并澄清列的来源。)
请尝试以下索引:
create index idx_user_email_id_name on user(email, id, name);
create index idx_profile_userid_type on profile(user_id, type);
create index idx_score_userid_type on score(user_id, type);
答案 1 :(得分:1)
您应该在profile
上提供score
和(type, user_id)
表复合索引。我不确定在索引中首先使用type
或user_id
是否更好,您应该尝试每一个并查看哪个更好;您可以使用EXPLAIN
来比较执行计划。
答案 2 :(得分:1)
您可以尝试在连接列上创建索引(如果不存在),并使用子查询而不是连接:
SELECT
id,
name,
(select info from profile where user_id = user.id AND type = 'language') as "info",
(select amount from score where user_id = user.id and type = 'total') as "amount"
FROM user
WHERE email = 'example@mail.com'
其他提示:检查执行计划,添加索引以避免在适当的情况下进行全表扫描,通过在必要时使用视图复制某些数据或使用视图来对表进行非规范化。