
Reduced queries for the project's dashboard
Problem * too mamy queries are occured when view project's dashboard. * this can consume all db connections in a very short time. * It took 2.5 minuetes to see the page in my local environment. Solution * Removed n+1 select queries. * After this commit, it takes only 900ms to load the page.
@621b4b86857812d98c18bf3eedcb6ff808929628
--- app/models/Issue.java
+++ app/models/Issue.java
... | ... | @@ -513,4 +513,28 @@ |
513 | 513 |
return Messages.get("common.time.default.day", JodaDateUtil.localDaysBetween(now, dueDate)); |
514 | 514 |
} |
515 | 515 |
} |
516 |
+ |
|
517 |
+ public static int countOpenIssuesByLabel(Project project, IssueLabel label) { |
|
518 |
+ return finder.where() |
|
519 |
+ .eq("project", project) |
|
520 |
+ .eq("labels", label) |
|
521 |
+ .findRowCount(); |
|
522 |
+ } |
|
523 |
+ |
|
524 |
+ public static int countOpenIssuesByAssignee(Project project, Assignee assignee) { |
|
525 |
+ return finder.where() |
|
526 |
+ .eq("project", project) |
|
527 |
+ .eq("assignee", assignee) |
|
528 |
+ .findRowCount(); |
|
529 |
+ } |
|
530 |
+ |
|
531 |
+ public static int countOpenIssuesByMilestone(Project project, Milestone milestone) { |
|
532 |
+ return finder.where() |
|
533 |
+ .eq("project", project) |
|
534 |
+ .eq("milestone", milestone) |
|
535 |
+ .findRowCount(); |
|
536 |
+ } |
|
537 |
+ |
|
538 |
+ |
|
539 |
+ |
|
516 | 540 |
} |
--- app/views/project/partial_dashboard_issuesbyassignee.scala.html
+++ app/views/project/partial_dashboard_issuesbyassignee.scala.html
... | ... | @@ -29,19 +29,19 @@ |
29 | 29 |
<a href="@routes.IssueApp.newIssueForm(project.owner, project.name)" target="_blank" class="ybtn ybtn-small">@Messages("issue.menu.new")</a> |
30 | 30 |
</div> |
31 | 31 |
} else { |
32 |
- @for(member <- project.members) { |
|
33 |
- @defining(countOpenIssuesBy(project, Map("assigneeId"->member.user.id.toString))) { assignedIssues => |
|
32 |
+ @for(assignee <- project.assignees) { |
|
33 |
+ @defining(Issue.countOpenIssuesByAssignee(project, assignee)) { assignedIssues => |
|
34 | 34 |
@defining(getPercent(assignedIssues, totalIssues)){ assignedPerc => |
35 | 35 |
@if(assignedIssues > 0){ |
36 | 36 |
<div class="row-fluid"> |
37 | 37 |
<div class="span6"> |
38 |
- <a href="@makeIssuesLink(project, scala.collection.immutable.Map("assigneeId"->member.user.id.toString))" |
|
39 |
- class="usf-group" title="@member.user.name (@{"@"}@member.user.loginId)"> |
|
38 |
+ <a href="@makeIssuesLink(project, scala.collection.immutable.Map("assigneeId"->assignee.user.id.toString))" |
|
39 |
+ class="usf-group" title="@assignee.user.name (@{"@"}@assignee.user.loginId)"> |
|
40 | 40 |
<span class="avatar-wrap smaller"> |
41 |
- <img src="@member.user.avatarUrl" width="20" height="20"> |
|
41 |
+ <img src="@assignee.user.avatarUrl" width="20" height="20"> |
|
42 | 42 |
</span> |
43 |
- <strong class="name">@member.user.name</strong> |
|
44 |
- <span class="loginid"> <strong>@{"@"}</strong>@member.user.loginId</span> |
|
43 |
+ <strong class="name">@assignee.user.name</strong> |
|
44 |
+ <span class="loginid"> <strong>@{"@"}</strong>@assignee.user.loginId</span> |
|
45 | 45 |
</a> |
46 | 46 |
</div> |
47 | 47 |
<div class="span3 num"> |
... | ... | @@ -58,7 +58,7 @@ |
58 | 58 |
} |
59 | 59 |
} |
60 | 60 |
|
61 |
- @defining(countOpenIssuesBy(project, Map("assigneeId"->User.anonymous.id.toString))) { notAssignedIssues => |
|
61 |
+ @defining(Issue.countOpenIssuesByAssignee(project, null)) { notAssignedIssues => |
|
62 | 62 |
@defining(getPercent(notAssignedIssues, totalIssues)) { notAssignedPerc => |
63 | 63 |
<div class="row-fluid"> |
64 | 64 |
<div class="span6"> |
--- app/views/project/partial_dashboard_issuesbylabel.scala.html
+++ app/views/project/partial_dashboard_issuesbylabel.scala.html
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 |
</a> |
41 | 41 |
</div> |
42 | 42 |
<div class="span2 num"> |
43 |
- <strong>@countOpenIssuesBy(project, Map("labelIds"->label.id.toString))</strong> |
|
43 |
+ <strong>@Issue.countOpenIssuesByLabel(project, label)</strong> |
|
44 | 44 |
</div> |
45 | 45 |
</div> |
46 | 46 |
} |
--- app/views/project/partial_dashboard_issuesbymilestone.scala.html
+++ app/views/project/partial_dashboard_issuesbymilestone.scala.html
... | ... | @@ -31,7 +31,7 @@ |
31 | 31 |
</div> |
32 | 32 |
} else { |
33 | 33 |
@for(milestone <- milestones){ |
34 |
- @defining(countOpenIssuesBy(project, Map("milestoneId"->milestone.id.toString))) { milestoneIssues => |
|
34 |
+ @defining(Issue.countOpenIssuesByMilestone(project, milestone)) { milestoneIssues => |
|
35 | 35 |
@if(milestoneIssues > 0){ |
36 | 36 |
<div class="row-fluid"> |
37 | 37 |
<div class="span6"> |
... | ... | @@ -52,7 +52,7 @@ |
52 | 52 |
} |
53 | 53 |
} |
54 | 54 |
|
55 |
- @defining(countOpenIssuesBy(project, Map("milestoneId"->Milestone.NULL_MILESTONE_ID.toString))) { notAssignedIssues => |
|
55 |
+ @defining(Issue.countOpenIssuesByMilestone(project, null)) { notAssignedIssues => |
|
56 | 56 |
<div class="row-fluid"> |
57 | 57 |
<div class="span6"> |
58 | 58 |
<a href="@makeIssuesLink(project, scala.collection.immutable.Map("milestoneId"->Milestone.NULL_MILESTONE_ID.toString))"> |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?