从MySQL中的100万条记录创建报告并在Java JSP页面中显示

时间:2013-11-01 13:30:46

标签: java mysql jsp

我正在研究一个包含3个表的MySQL数据库 - workout_data,excercises和sets tables。我面临与基于这三个表生成报告相关的问题。

要添加更多信息,可以使用许多套装来锻炼身体,并且可以锻炼一些锻炼。 我目前拥有从这些表中的数据生成报告的指标。我将在本周创建过去42天的报告。在我通过加入这些表获得报告时,查询会运行很长时间。

例如 - 集合表在过去的42天内有超过100万条记录。此表中的id是excercise表中的excercise_id。 excercise表的id是workout_data表中的workout_id。

我正在运行此查询,获取数据需要10分钟以上。我必须准备一份报告并在浏览器中向用户显示。但是由于这个长时间运行的查询,网页超时并且用户无法看到报告。

有关如何实现这一目标的任何建议吗?

        SELECT REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID,
               REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER 
          FROM EXCERCISES 
    INNER JOIN REPORTSETS ON EXCERCISES.ID=REPORTSETS.EXCERCISE_ID 
         where user_id=(select id from users where email='testuser1@gmail.com') 
           and substr(set_date,1,10)='2013-10-29' 
      GROUP BY REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID,
               REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER

4 个答案:

答案 0 :(得分:1)

您可能想要查看的SQL注释:

1)你有USER_ID和SET_DATE的索引吗?

2)您的SET_DATE数据类型看起来不对,是varchar吗?将其存储为日期将意味着数据库可以更有效地优化您的搜索。目前,每个查询将调用substring方法无数次,因为必须为where子句的第一部分返回的每一行运行它。

3)该组真的需要吗?除非我遗漏了某些内容,否则声明中的“分组”部分不会带来任何结果;)

答案 1 :(得分:1)

两件事:

首先,您有以下WHERE子句项来提取一天的数据。

  AND substr(set_date,1,10)='2013-10-29'

这最终使得在日期使用索引失败了。如果您的set_date列的数据类型为DATETIME,那么您需要的是

  AND set_date >= `2013-10-09`
  AND set date <  `2013-10-09` + INTERVAL 1 DAY

这将允许对set_date上的索引使用范围扫描。在我看来,你可能想要(user_id, set_date)上的复合索引。但是你应该用EXPLAIN来弄清楚是否正确。

其次,你误导了GROUP BY。除非您在查询中使用某种汇总函数,例如SUM()GROUP_CONCAT(),否则该子句毫无意义。你想要ORDER BY吗?

答案 2 :(得分:0)

如果您可以将日期存储为日期或以进行比较所需的格式存储,则应该会产生显着差异。在每个日期执行substr()调用必须非常耗时。

答案 3 :(得分:-1)

调整查询的建议当然有助于提高查询速度。但我认为这里的要点是在会话超时之前可以使用超过100万条记录。如果您有2或3百万条记录,那么一些性能调整会解决问题吗?我不这么认为。所以:

1)如果要在浏览器上显示,请使用分页和查询(例如)前100条记录 2)如果要生成报告(如pdf),则使用异步方法(JMS)