zoukankan      html  css  js  c++  java
  • 老李分享:大数据性能调优案例

    老李分享:大数据性能调优案例

    1、“空间换时间”以及“内存中处理数据”

    比如user_id.csv文件中有20万个不同的user_id,根据user_id去查其对应的用户最近发表的一篇帖子,取出post_id,post_title、post_time和user_id(post表中查,post表中有一列是user_id,表示帖子所属者),而帖子数目有大概两百万,那么如何处理呢?
    我的解决方案是:
    A. 先将post表post_id,post_title、post_time和user_id这四列导出到posts.csv文件中,然后利用一个CSV读取组件将posts.csv文件中的记录读取到csvRecords中
    B. 然后利用“空间换时间的思想”,先将user_id.csv中的user_id读取到userIdList的List对象中,然后再将userIdList转为字典:
    var userIdDict = userIdList.Distinct().ToDictionary(c => c, c => 1);
    C. 最后比对userIdDict和csvRecords得到结果:
    var resultRecords = csvRecords.Where(c => postDict.ContainsKey(c.UserId)).ToList(); // 这里ContainsKey的查询时间复杂度为O(1)

    2、JOIN优化查询性能
    一个页面查询效率非常低(一分多钟都没有结果),查询过程后台执行了3条SQL,其中2条SQL的执行时间都在39秒左右(2条SQL类似),造成数据库连接超时。
    后台数据库查询用的是EF框架,而EF框架使用不当的话很容易导致糟糕的查询性能。
    简单地模拟下(数据库表名已调整,记录数也有所改动,不影响结果):
    用2张表:一张表为账户表比如account,记录数大概为3000条。另外一张表比如为帖子表post,记录数大概为190万。
    然后后台处理过程大概是:先根据查询条件取得账户表的account_id的列表accountIds,然后再根据account_id列表去找post记录(post表有一个字段为account_id),大概这样:
    var posts= db.Posts.Where(m).Where(c => accountIds.Contains(c.AccountId));
    不需要过于关注这行代码,我用工具监测到这行代码对应的SQL为:
    SELECT * from post
    WHERE
    ((20 = account_id) OR (21 = account_id)) OR ...
    ORDER BY created_at DESC
    LIMIT 0, 15;
    上面的OR条件大概有2000多个。EXPLAIN结果显示ROWS值达到134万多,也没有使用索引。
    因为多了ORDER BY子句造成效率低,但是不能为了优化而省掉它,因为业务要求第一页显示最近的15篇帖子。
    用JOIN查询,自己手工拼了一条SQL,发现几乎瞬间出结果,SQL大概如下:
    SELECT * FROM 
    posts AS A
    JOIN
    accounts AS B
    ON A.account_id = B.id
    WHERE A.category = 1 # 帖子的分类
    ORDER BY A.created_at DESC
    LIMIT 0, 15;
    按照这个方法,舍弃EF,改用拼SQL的方法重写代码了。速度改进不少,原来需要近2分钟才能显示查询结果,现在只需要3-4秒。
    这个场景用JOIN能提高查询效率,是因为一张表的记录数只有3000条左右,而另外一张有几百万的数据。如果两张表的数据都有几百万,那用JOIN未必能提高查询效率

    3、业务逻辑代码层面优化
    理解透彻业务逻辑,去除冗余业务逻辑代码

    原文链接;http://www.cnblogs.com/laoli0201

     

  • 相关阅读:
    Android java.lang.UnsupportedClassVersionError: com/android/dx/command/Main : Unsupported major.minor ver
    Android EditText光标位置(定位到最后)
    Android EditText获取光标位置并插入字符删除字符
    Android 仿微信小视频录制
    Android仿微信小视频录制功能
    Android消息机制之实现两个不同线程之间相互传递数据相互调用
    Android Data Binding 技术
    Android中解析XML
    Android 怎样把光标放在EditText中文本的末尾处?
    Hadoop HBase概念学习系列之RowKey设计(二十九)
  • 原文地址:https://www.cnblogs.com/poptest/p/4874996.html
Copyright © 2011-2022 走看看