From 8515b33664c1d6760cd49bdfa764471e0629d631 Mon Sep 17 00:00:00 2001 From: Menci Date: Sun, 21 Apr 2019 10:58:34 +0800 Subject: [PATCH] Optimize count queries for pagination --- models/common.ts | 7 +++++++ modules/contest.js | 4 ++-- modules/discussion.js | 6 +++--- modules/problem.js | 4 ++-- modules/user.js | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/models/common.ts b/models/common.ts index a19c911..5a15346 100644 --- a/models/common.ts +++ b/models/common.ts @@ -26,6 +26,13 @@ export default class Model extends TypeORM.BaseEntity { )[0]['COUNT(*)']); } + static async countForPagination(where) { + const queryBuilder = where instanceof TypeORM.SelectQueryBuilder + ? where + : this.createQueryBuilder().where(where); + return await queryBuilder.getCount(); + } + static async queryAll(queryBuilder) { return await queryBuilder.getMany(); } diff --git a/modules/contest.js b/modules/contest.js index 33b76a9..beee933 100644 --- a/modules/contest.js +++ b/modules/contest.js @@ -14,7 +14,7 @@ app.get('/contests', async (req, res) => { if (res.locals.user && res.locals.user.is_admin) where = {} else where = { is_public: true }; - let paginate = syzoj.utils.paginate(await Contest.count(where), req.query.page, syzoj.config.page.contest); + let paginate = syzoj.utils.paginate(await Contest.countForPagination(where), req.query.page, syzoj.config.page.contest); let contests = await Contest.queryPage(paginate, where, { start_time: 'DESC' }); @@ -369,7 +369,7 @@ app.get('/contest/:id/submissions', async (req, res) => { query.andWhere('type = 1') .andWhere('type_info = :contest_id', { contest_id }); - let paginate = syzoj.utils.paginate(await JudgeState.countQuery(query), req.query.page, syzoj.config.page.judge_state); + let paginate = syzoj.utils.paginate(await JudgeState.countForPagination(query), req.query.page, syzoj.config.page.judge_state); let judge_state = await JudgeState.queryPage(paginate, query, { submit_time: 'DESC' }); diff --git a/modules/discussion.js b/modules/discussion.js index a004705..840287d 100644 --- a/modules/discussion.js +++ b/modules/discussion.js @@ -16,7 +16,7 @@ app.get('/discussion/:type?', async (req, res) => { } else { where = { problem_id: null }; } - let paginate = syzoj.utils.paginate(await Article.count(where), req.query.page, syzoj.config.page.discussion); + let paginate = syzoj.utils.paginate(await Article.countForPagination(where), req.query.page, syzoj.config.page.discussion); let articles = await Article.queryPage(paginate, where, { sort_time: 'DESC' }); @@ -52,7 +52,7 @@ app.get('/discussion/problem/:pid', async (req, res) => { } let where = { problem_id: pid }; - let paginate = syzoj.utils.paginate(await Article.count(where), req.query.page, syzoj.config.page.discussion); + let paginate = syzoj.utils.paginate(await Article.countForPagination(where), req.query.page, syzoj.config.page.discussion); let articles = await Article.queryPage(paginate, where, { sort_time: 'DESC' }); @@ -85,7 +85,7 @@ app.get('/article/:id', async (req, res) => { article.content = await syzoj.utils.markdown(article.content); let where = { article_id: id }; - let commentsCount = await ArticleComment.count(where); + let commentsCount = await ArticleComment.countForPagination(where); let paginate = syzoj.utils.paginate(commentsCount, req.query.page, syzoj.config.page.article_comment); let comments = await ArticleComment.queryPage(paginate, where, { diff --git a/modules/problem.js b/modules/problem.js index 7b2c31c..8b4e744 100644 --- a/modules/problem.js +++ b/modules/problem.js @@ -35,7 +35,7 @@ app.get('/problems', async (req, res) => { query.orderBy(sort, order.toUpperCase()); } - let paginate = syzoj.utils.paginate(await Problem.countQuery(query), req.query.page, syzoj.config.page.problem); + let paginate = syzoj.utils.paginate(await Problem.countForPagination(query), req.query.page, syzoj.config.page.problem); let problems = await Problem.queryPage(paginate, query); await problems.forEachAsync(async problem => { @@ -98,7 +98,7 @@ app.get('/problems/search', async (req, res) => { query.addOrderBy(sort, order.toUpperCase()); } - let paginate = syzoj.utils.paginate(await Problem.countQuery(query), req.query.page, syzoj.config.page.problem); + let paginate = syzoj.utils.paginate(await Problem.countForPagination(query), req.query.page, syzoj.config.page.problem); let problems = await Problem.queryPage(paginate, query); await problems.forEachAsync(async problem => { diff --git a/modules/user.js b/modules/user.js index aad8f5a..24ac11c 100644 --- a/modules/user.js +++ b/modules/user.js @@ -12,7 +12,7 @@ app.get('/ranklist', async (req, res) => { if (!['ac_num', 'rating', 'id', 'username'].includes(sort) || !['asc', 'desc'].includes(order)) { throw new ErrorMessage('错误的排序参数。'); } - let paginate = syzoj.utils.paginate(await User.count({ is_show: true }), req.query.page, syzoj.config.page.ranklist); + let paginate = syzoj.utils.paginate(await User.countForPagination({ is_show: true }), req.query.page, syzoj.config.page.ranklist); let ranklist = await User.queryPage(paginate, { is_show: true }, { [sort]: order.toUpperCase() }); await ranklist.forEachAsync(async x => x.renderInformation());