sql优化:数据量过⼤查询优化
1.场景:有⼤数据的数据需要放到⾸页统计,⼀般就是聚合、分组之类的,按照年⽉⽇进⾏查询和统计。如果数据量⽐较少,⼏⼗万数据没什么问题。但是随着数据量的增多,查询速度越来越慢。这个时候就需要去优化了~
刚开始⾃⼰的想法是这样的:使⽤多线程的⽅式,因为查询每天的数据量很少,那么是不是可以使⽤多线程的⽅式,每个线程查询⼀天的,查询⼀个⽉30天,就⽤30个线程,这样速度会不会快些?
于是,⽤多线程的⽅式实现了下。代码如下:
private ExecutorService executorService = new ThreadPoolExecutor(30,30,1, TimeUnit.MILLISECONDS,new LinkedBlockingDeque<>());
public List<Map> getCiServiceBadEvaNumStatistic(SAASIndexQuery saasIndexQuery) throws InvocationTargetException, IllegalAccessException {
String startDate = StartDate();
String endDate = EndDate();
int days = DatebetweenOfDayNum(DateUtil.parseDate(startDate,DateUtil.dateFormatPattern),DateUtil.parseDate(endDate,DateUtil.dateFormatPattern));        CompletionService<List<CiOrderStatisticSection>> completionService = new ExecutorCompletionService<List<CiOrderStatisticSection>>(executorService);
List<CiOrderStatisticSection> allList = new ArrayList<>();
long start = System.currentTimeMillis();
logger.info("测试异步时间start:" + System.currentTimeMillis());
//CountDownLatch countDownLatch = new CountDownLatch(days);
SAASIndexQuery everyDaySaas = new SAASIndexQuery();
for(int i = 0;i<days;i++){
everyDaySaas.setStartDate(DateUtil.StartDate(),i,DateUtil.dateFormatPattern));
everyDaySaas.setEndDate(DateUtil.StartDate(),1,DateUtil.dateFormatPattern));
//untDown();
int finalI = i;
completionService.submit(new Callable<List<CiOrderStatisticSection>>() {
@Override
public List<CiOrderStatisticSection> call() throws Exception {
//allList.CiServiceNegativeRate(saasIndexQuery));
//untDown();
System.out.println("====="+ finalI +"=====");
CiServiceNegativeRate(saasIndexQuery);
}
});
}
System.out.println("==============" + (System.currentTimeMillis()-start) + "毫秒");
long t = System.currentTimeMillis();
for (int i = 0;i<days;i++){
System.out.println("for循环耗时==============+"+i + (System.currentTimeMillis()-t) + "毫秒");
try {
Future<List<CiOrderStatisticSection>> future = completionService.take();
List<CiOrderStatisticSection>  ciList = ();
allList.addAll(ciList);
} catch (InterruptedException e) {
e.printStackTrace();
sql优化的几种方式} catch (ExecutionException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
logger.info("测试异步时间end:" + (end-start) + "毫秒");
System.out.println("测试异步时间end:" + (end-start) + "毫秒");
}
测试后发现不对,使⽤多线程的take⽅式每次都会有阻塞,这个阻塞⼀直没明⽩是哪⾥阻塞了?是线程池、LinkedBlockingDeque 还是for 循环 take时候阻塞了⼀直没明⽩,观察的结果就是每次for循环都要差不多200多毫秒,30个循环要6s多。。。。额,算了,还没有原来快呢
2.昨天换了种思路:直接从数据库查询时候做好控制。每次查询先根据⽉份和年份,查询出来id的最⼤值和最⼩值,之后sql⾥⾯查询时候加上id在这个最⼤值和最⼩是区间内。⼤概思路是这样:嗯,结果竟然可以。