首先,第一件事:我一直在寻找类似的问题,但没有发现任何可以解释为什么我在做的事情是不好的做法,因此即使这是非常基本的东西,我也要发布一个新问题。
我已经收到投诉,说我对数据库的压力太大,但是我不知道如何优化,所以我在这里寻求帮助。
我在底部附加了一张我要处理的结构的图片。我想做的是以下几点:
我需要获得执行特定userAction的人员的列表(让我们说“ viewProduct”,然后添加有关该人员的userAge,国家/地区和大陆的信息)。
香港专业教育学院写了以下内容:
select u.userId, u.userAge, c.countryName, co.name, ul.createdTime,
ul.userAction
from user_log as ul
left join user as u ON u.userId = ul.userId
left join country as c ON c.id = u.userCountryId
left join continent as co ON co.id = c.continentId
where ul.createdTime > '2016-06-01'
and u.userAge > 40
and (ul.userAction like 'viewProduct'
or ul.userAction like 'storeProduct'
or ul.userAction like 'addProduct'
);
而且这显然还不够好,所以我衷心希望有人可以帮助您提高效率。我不太习惯处理条目数亿的表。
先感谢您!
db structure
最佳答案
查询中有几个问题:
如果您没有限制并且没有索引-MySQL将检查user_log中的所有100000000条记录以给出结果。要减少已处理记录的数量,请在“ ul.createdTime”和“ ul.userAction”中添加索引。这甚至可以由组成的索引(createdTime,userAction)组成。
“ ul.userAction之类的'viewProduct'”等于“ ul.userAction ='viewProduct'”。并且可以将整个构造重构为“(.viewProduct”,“ storeProduct”,“ addProduct”)中的ul.userAction。
将“ u.userAge> 40”移动到加入条件。而且在“ u.userAge”上的索引也会有很大帮助。
我不确定,这取决于您的数据,但是有时“内部加入用户身份为u”可能比“左加入用户身份为”更快。因此,您可以在这里玩。 (但是查询逻辑将改变)
向具有100000000条记录的表添加索引是一项艰巨的任务。因此,出于测试目的,我将仅复制最后1000000条记录的“ user_log”并评估其性能。然后,我将添加所有提到的索引并测试此查询:
select u.userId, u.userAge, c.countryName, co.name, ul.createdTime, ul.userAction
from user_log as ul
left join user as u
on u.userId = ul.userId and u.userAge > 40
left join country as c
on c.id = u.userCountryId
left join continent as co
on co.id = c.continentId
where ul.createdTime > '2016-06-01' and
ul.userAction in('viewProduct', 'storeProduct', 'addProduct');
..并比较效果。
请让我们知道,这对您有帮助吗?