我们在做一个统计页面时,原来大约有1000万左右的数据进行查询,还可以接受,但是随着业务量的增大,目前有3000多万的数据来统计,一次统计出查询结果就很慢很慢,有时候会出现超时异常。
为了解决这个问题,我们使用分项加载的统计策略。主要的策略是把统计页面的每一个统计项找一个key,然后分项查询得出结果。这样能够提高用户的体验。
主要是两方面的改进。
一是前端页面进行修改
loadData() {//分两步,先取出检查项,填写到表里面。console.log("第一步,取出检查项");getCheckItemsStatistics({year: this.selectedYear,month: this.selectedMonth,areaNumbers: this.selectedAreaNumber,foodTypes: this.selectedFoodTypes,itemDepth: this.selectedItemDepth}).then(async response => {if (response.state == 200) {const itemNumbers = [];for (const item of response.data) {// 在这里对每个 item 进行处理// 例如获取某个键的值const itemNumber = item['_ITEMNUMBER'];itemNumbers.push(itemNumber);}//补充其它的值为0this.tableData = this.processKey(response.data);this.isLoading = false;//console.log("第二步,取出检查项的统计数据");let rowNumber = 0;for (const itemNumber of itemNumbers) {//console.log("细分第二步,查询" + itemNumber + "的统计数据");// 假设这是你的计算逻辑this.tableData.at(rowNumber)['loading'] = true;// for (const row of this.tableData) {// row.loading = true; // 开始计算前设置加载状态为trueawait getCheckEveryItemStatistics({year: this.selectedYear,month: this.selectedMonth,areaNumbers: this.selectedAreaNumber,itemNumber: itemNumber,foodTypes: this.selectedFoodTypes,itemDepth: this.selectedItemDepth,isAreasCondition: this.isAreasCondition}).then(async response1 => {if (response1.state == 200) {//console.log("细分第三步,取出" + itemNumber + "的统计数据"+JSON.stringify(response1.data));for (const obj of this.tableData) {if (obj['_ITEMNUMBER'] == itemNumber) {obj['SUM_COUNT'] = response1.data[0]['SUM_COUNT'];obj['TRUE_COUNT'] = response1.data[0]['TRUE_COUNT'];obj['FALSE_COUNT'] = response1.data[0]['FALSE_COUNT'];obj['MISSING_COUNT'] = response1.data[0]['MISSING_COUNT'];obj['TRUE_PCT'] = response1.data[0]['TRUE_PCT'];obj['FALSE_PCT'] = response1.data[0]['FALSE_PCT'];obj['MISSING_PCT'] = response1.data[0]['MISSING_PCT'];}}}}).catch(() => {}).finally(() => {//this.isLoading=false;})this.tableData.at(rowNumber)['loading'] = false; // 计算完成后设置加载状态为falserowNumber++;}// }}}).catch(err => {}).finally(() => {this.isLoading = false;})//这是原来的代码,上面是改进的代码// getCheckItemsCheckSummaryStatistics({// year: this.selectedYear,// month: this.selectedMonth,// areaNumbers: this.selectedAreaNumber,// itemNumber:'1.1',// foodTypes: this.selectedFoodTypes,// itemDepth: this.selectedItemDepth,// isAreasCondition: this.isAreasCondition// }).then(response => {// if(response.state == 200) {// this.tableData = this.processKey(response.data);// }// }).catch(() => {// }).finally(() => {// this.isLoading = false;// });},
二是后台页面添加统计项参数
@RequestMapping(value = "/getCheckEveryItemStatistics", method = {RequestMethod.POST})APIResult<List<Map<String, Object>>> getCheckEveryItemStatistics(@RequestParam(required = false) String year,@RequestParam(required = false) String month,@RequestParam(required = false) String areaNumbers,@RequestParam(required = true) String itemNumber,@RequestParam(required = false) String foodTypes,@RequestParam(required = false) Integer itemDepth,@RequestParam(required = false) boolean isAreasCondition);
三是对统计图添加自动计算规则
<div class="chart-box"><vue-chart:id="id":option="chartOption"width="calc(100% - 40px)"height="350px"/></div>
computed: {chartOption() {const option = this.dataOption;let trueCount = 0;let falseCount = 0;let missingCount = 0;this.tableData.forEach(item => {trueCount += item['TRUE_COUNT'];falseCount += item['FALSE_COUNT'];missingCount += item['MISSING_COUNT'];});option.series[0].data = [{value: trueCount, name: '评价(是)'},{value: falseCount, name: '评价(否)'},{value: missingCount, name: '评价(合理缺项)'}];return JSON.parse(JSON.stringify(option));}},