美文网首页
如何优化大数据量的方法

如何优化大数据量的方法

作者: DreamsonMa | 来源:发表于2018-11-14 21:53 被阅读0次

随着项目上线,业务数据会越来越多。这个时候,很多开发时适用的方法、任务,在庞大数据量面前就会变得很不堪,经常会出现超时,慢查询,异常等等问题。

所以,一般在开发阶段,我们怎么能避免这些问题呢?一切皆有套路。

一般处理套路:
SQL优化,数据库加索引,多线程,并行计算,异步处理,大事务拆小事务,缓存,数据异构等等。

今天分享一个通过时间维度优化SQL的方法。说白了,就是如何将时间拆小。

还是直接贴代码:

开始版本,按天拆分时间:

/**
     * 按给定的天数切割时间段
     * @param startDate
     * @param endDate
     * @param amount 按多少天切割
     * @return
     * @throws ParseException
     */
    public static List<TimeSlot> splitTimeSlot(Date startDate, Date endDate, Integer amount) throws ParseException {
        Calendar canlandar1 = Calendar.getInstance();//开始时间
        Calendar canlandar2 = Calendar.getInstance();//结束时间
        canlandar1.setTime(com.midea.ec.fc.impl.utils.DateUtils.getDateStartTime(startDate));
        canlandar2.setTime(com.midea.ec.fc.impl.utils.DateUtils.getDateStartTime(endDate));
        List<TimeSlot> returnList = new ArrayList<TimeSlot>();
        while(canlandar1.compareTo(canlandar2) < 1){
            TimeSlot timeSlot = new TimeSlot();
            Date start = canlandar1.getTime();
            canlandar1.add(Calendar.DATE, amount);//每次循环增加amount天
            Date end = canlandar1.getTime();
            timeSlot.setStartDate(DateTool.getDateTime(start));
            timeSlot.setEndDate(DateTool.getDateTime(end.before(canlandar2.getTime()) ? end : canlandar2.getTime()));
            returnList.add(timeSlot);
            timeSlot.setStartDateTime(start);
            timeSlot.setEndDateTime(end.before(canlandar2.getTime()) ? end : canlandar2.getTime());
        }
        return returnList;
    }

发现某些天数据量大跑不动了,然后继续拆分成小时:

public static List<TimeSlot> splitTimeSlotByHour(String startDate, String endDate) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = format.parse(startDate);
        Date date2 = format.parse(endDate);

        Calendar canlandar1 = Calendar.getInstance();//开始时间
        Calendar canlandar2 = Calendar.getInstance();//结束时间
        canlandar1.setTime(date1);//2016-11-01
        canlandar2.setTime(date2);//2016-11-11
        List<TimeSlot> returnList = new ArrayList<TimeSlot>();
        while(canlandar1.compareTo(canlandar2) < 1){
            TimeSlot timeSlot = new TimeSlot();
            Date start = canlandar1.getTime();
            canlandar1.add(Calendar.HOUR, 1);//每次循环增加一天
            Date end = canlandar1.getTime();
            timeSlot.setStartDate(DateTool.getDateTime(start));
            timeSlot.setEndDate(DateTool.getDateTime(end));
            returnList.add(timeSlot);
            timeSlot.setStartDateTime(start);
            timeSlot.setEndDateTime(end);
        }
        if(CollectionUtils.isNotEmpty(returnList)) returnList.remove(returnList.size()-1);
        return returnList;
    }

最后发现光棍节的这天,小时也跑不动了,还要继续拆分钟?改成自己拆吧。

/**
 * @Auther: majx2
 * @Date: 2018-11-14 11:24
 * @Description:
 */
public class JobTimeoutHelper {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 时间区间拆分数量    
private int intervalCount = 3;
// 拆分最大层级
    private int maxCount = 3;

    private JobTimeoutHelper(){}
    public static JobTimeoutHelper create(){
        return new JobTimeoutHelper();
    }

    public void splitTime(Date startDate,Date endDate,String jobName,TimeSplitHandler handler){
        splitTime(startDate,endDate,0,jobName,handler);
    }

    public void splitTime(Date startDate,Date endDate,int level,String jobName,TimeSplitHandler handler){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(level>=maxCount){
            logger.info("{}超时,拆分已到上限,无法继续拆分:时间:{}",jobName,MessageFormat.format("开始时间:{0},结束时间:{1}",df.format(startDate),df.format(endDate)));
            return;
        }
        level++;
        if(startDate.compareTo(endDate) < 1) {
            long offset = startDate.getTime();
            long diff = endDate.getTime() - offset;
            long interval = diff/intervalCount;
            for (int i = 0 ; i <intervalCount;i++){
                Date start = new Date(offset);
                Date end ;
                if(i == (intervalCount-1)){
                    end = endDate;
                }else{
                    offset += interval;
                    end =  new Date(offset);
                }
                try{
                    logger.info("{}处理开始,层级:{},时间:{}", jobName,level,MessageFormat.format("开始时间:{0},结束时间:{1}",df.format(start),df.format(end)));
                    handler.deal(start,end);
                    logger.info("{}处理结束,层级:{},时间:{}", jobName,level,MessageFormat.format("开始时间:{0},结束时间:{1}",df.format(start),df.format(end)));
                }catch (MySQLNonTransientConnectionException ex){
                    logger.info("{}超时,进行拆分处理,层级:{}",jobName,level);
                    splitTime(start,end,level,jobName,handler);
                } catch (Exception e) {
                    logger.error("{}异常啦:{}",jobName, ExceptionUtils.getFullStackTrace(e));
                }
            }
        }
    }

    public interface TimeSplitHandler{
        void deal(Date start,Date end) throws Exception;
    }

    public JobTimeoutHelper setIntervalCount(int intervalCount) {
        this.intervalCount = intervalCount;
        return this;
    }

    public JobTimeoutHelper setMaxCount(int maxCount){
        this.maxCount = maxCount;
        return this;
    }


    public static void main(String[] args) {
        final Date today = new Date();
        final Date tomorrow = DateUtils.addDays(today, +1);
        final Date yestoday = DateUtils.addDays(today, -1);
        JobTimeoutHelper.create().setIntervalCount(2).setMaxCount(3)
                .splitTime(yestoday, tomorrow,"JobTimeoutHelper", new TimeSplitHandler() {
            @Override
            public void deal(Date start, Date end) throws Exception {
                throw new MySQLNonTransientConnectionException();
            }
        });
    }
}

这是一个任务超时帮助类,原来是通过递归的方式,不断将时间拆小,这样在庞大的数据面前也可以淡定的run起来。只需要多花点时间而已。同时,也可以配合多线程处理,让程序加速奔跑起来。

温馨提示:要根据实际需求,记得要设置多少等份,和最大层级哦。

相关文章

  • 高性能mysql

    各种数据结构的特性 大数据量 优化方法 值得优化的查询 计数表

  • 如何优化大数据量的方法

    随着项目上线,业务数据会越来越多。这个时候,很多开发时适用的方法、任务,在庞大数据量面前就会变得很不堪,经常会出现...

  • 大数据工程师常用的优化方法

    优化人员工作时免不了要接触到大数据量的问题,下面就将平时收集的一些关于大数据量的优化方法整理记录一下,也是和大家一...

  • Android--Canvas绘制优化

    onDraw( ) 是同步方法 ,如果同时绘制的数据量太大就会卡顿 (例如100万个坐标点); 优化方法如下: 数...

  • 性能调优之SQL优化

    如何加快查询速度?1、升级硬件2、根据查询条件,建立索引,优化索引、优化访问方式,限制结果集的数据量。3、扩大服务...

  • 抓取数据瓶颈彻底解决

    用昨天优化的方法,一个晚上累计了600多探测的数据量,其中数据合格的在45-50%,还没统计出具体的有效数据量。 ...

  • SQL优化(收集)

    如何加快查询速度? 升级硬件 根据查询条件,建立索引,优化索引,优化访问方式,限制结果集的数据量。 扩大服务器的内...

  • 关于iOS数据库大数据量的优化策略

    前言: 对于目前的iOS应用,大的数据量操作是一个不可避免的问题,本文仅对sqlite数据库大数据量操作进行优化策...

  • 测试是教育游戏优化的基本方法

    教育游戏优化是一个持续不断的过程,如何掌握优化的方法论,如何使得优化更加有效果?测试是一个基本的方法。 在测试过程...

  • ListView和RecyclerView

    ListView ListView 性能如何优化 (主要在getView方法上优化:复用view,ViewHold...

网友评论

      本文标题:如何优化大数据量的方法

      本文链接:https://www.haomeiwen.com/subject/fqusfqtx.html