首先,第一件事:我一直在寻找类似的问题,但没有发现任何可以解释为什么我在做的事情是不好的做法,因此即使这是非常基本的东西,我也要发布一个新问题。

我已经收到投诉,说我对数据库的压力太大,但是我不知道如何优化,所以我在这里寻求帮助。

我在底部附加了一张我要处理的结构的图片。我想做的是以下几点:
我需要获得执行特定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');


..并比较效果。

请让我们知道,这对您有帮助吗?

08-16 13:40