从100万创建报告+;MySQL中的记录和Java JSP页面中的显示
我正在处理一个MySQL数据库,它有3个表——锻炼数据、练习和设置表。我面临着基于这三个表生成报告的相关问题 要添加更多信息,一系列练习将构成一个练习,而一系列练习将成为一项锻炼。 我目前拥有从这些表中的数据生成报告的指标。我必须生成过去42天(包括本周)的报告。当我通过连接这些表获得报告时,查询运行了很长时间 例如,仅在过去42天内,sets表就有超过100万条记录。此表中的id是练习表中的练习\ U id。练习表的id是训练数据表中的训练id 我正在运行此查询,获取数据需要10分钟以上。我必须准备一份报告并在浏览器中向用户显示。但是由于这个长时间运行的查询,网页超时,用户无法看到报告 有没有关于如何实现这一目标的建议从100万创建报告+;MySQL中的记录和Java JSP页面中的显示,java,mysql,jsp,Java,Mysql,Jsp,我正在处理一个MySQL数据库,它有3个表——锻炼数据、练习和设置表。我面临着基于这三个表生成报告的相关问题 要添加更多信息,一系列练习将构成一个练习,而一系列练习将成为一项锻炼。 我目前拥有从这些表中的数据生成报告的指标。我必须生成过去42天(包括本周)的报告。当我通过连接这些表获得报告时,查询运行了很长时间 例如,仅在过去42天内,sets表就有超过100万条记录。此表中的id是练习表中的练习\ U id。练习表的id是训练数据表中的训练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
当然,调整查询的建议将有助于提高查询速度。但我认为这里的要点是,在会话超时之前,可以使用超过100万条记录来做什么。如果您有大约200万或300万条记录,进行一些性能调整可以解决问题吗?我不这么认为。因此: 1) 如果要在浏览器上显示,请使用分页和查询(例如)前100条记录。
2) 如果您想生成报告(如pdf),那么使用异步方法(JMS)如果您可以将日期存储为日期,或者存储为进行比较所需的格式,那么应该会有很大的不同。对每个日期执行substr()调用都必须非常耗时。您可能希望查看的SQL注释: 1) 你有关于用户ID和设置日期的索引吗 2) 设置日期的数据类型看起来有误,是varchar吗?将其存储为日期将意味着数据库可以更有效地优化您的搜索。目前,每个查询都会调用substring方法无数次,因为它必须对where子句第一部分返回的每一行运行 3) 是否真的需要团队成员?除非我遗漏了什么,否则语句中的“分组依据”部分不会带来任何结果;) 有两件事: 首先,您有以下WHERE子句项来提取一天的数据
AND substr(set_date,1,10)='2013-10-29'
这完全不利于在日期上使用索引。如果您的set\u date
列具有DATETIME
数据类型,您需要的是
AND set_date >= `2013-10-09`
AND set date < `2013-10-09` + INTERVAL 1 DAY
和set_date>=`2013-10-09`
并设置日期<`2013-10-09`+间隔1天
这将允许在设置日期对索引使用范围扫描。在我看来,您可能需要一个关于(用户id,设置日期)
的复合索引。但是你应该仔细解释一下这是否正确
第二,您误用了
分组方式。除非您在查询中有某种摘要函数,如SUM()
或GROUP\u CONCAT()
,否则该子句毫无意义。你想按
排序吗?我认为问题不在于如何在浏览器中显示1m记录。这是生成报告所需的时间。但他指的是哪种报告?如果它只是浏览器中显示的一个表,那么为什么不首先处理少量记录(这里我指的是分页)如果set_date列实际上是一个varchar列,那么将其更改为DATETIME。认真地这将对性能有很大帮助。