我已经使用pg-promise在Express中开发了一个API,并且通过在查询中设置OFFSET使用分页。当我运行请求时,不到3秒即可收到第1页的响应。但是随着页面的增加,响应时间也会增加。第2页花费6991毫秒,第3页花费21秒,第4页花费44秒,依此类推。为什么会这样呢?随着页面增加1,每次获得响应的时间几乎增加一倍。我是一个初学者,我无法弄清楚这里出了什么问题。该查询将为各个页面返回正确的结果。但是我不知道为什么要花这么长时间才能得到答复。以下是我的代码:
router.get('/', function (req, res) {
var type = req.query.type;
var country = decodeURI(req.query.country);
var phase = req.query.phase;
var page = req.query.page;
var adjuvant = req.params.adjuvant;
var metastatic = req.params.metastatic;
var city = req.params.city;
var gene = req.params.gene;
const query =
`SELECT json_build_object('nct_id', s.nct_id, 'overall_status', s.overall_status, 'phase', s.phase, 'brief_title', s.brief_title, 'country', countries.name, 'eligibilities',
(SELECT json_agg(json_build_object('criteria', e.criteria, 'gender', e.gender))
FROM eligibilities e WHERE s.nct_id = e.nct_id), 'facilities',
(SELECT json_agg(json_build_object('status', f.status, 'name', f.name, 'city', f.city, 'country', f.country, 'facility_contacts',
(SELECT json_agg(json_build_object('contact_type', fc.contact_type, 'name', fc.name, 'email', fc.email, 'phone', fc.phone))
FROM facility_contacts fc WHERE fc.facility_id = f.id)))
FROM facilities f WHERE s.nct_id = f.nct_id AND f.country LIKE $1 AND f.status NOT SIMILAR TO '(Suspended|Withheld|Completed|No longer available|Withdrawn|Terminated)' AND f.city SIMILAR TO $7), 'interventions',
(SELECT json_agg(json_build_object('intervention_type', i.intervention_type, 'name', i.name, 'description', i.description))
FROM interventions i WHERE s.nct_id = i.nct_id), 'design_groups',
(SELECT json_agg(json_build_object('group_type', dg.group_type, 'title', dg.title, 'description', dg.description))
FROM design_groups dg WHERE s.nct_id = dg.nct_id), 'sponsors',
(SELECT json_agg(json_build_object('agency_class', sp.agency_class, 'lead_or_collaborator', sp.lead_or_collaborator, 'name', sp.name))
FROM sponsors sp WHERE s.nct_id = sp.nct_id)) json
FROM studies s
INNER JOIN countries ON countries.name SIMILAR TO $1 AND countries.nct_id = s.nct_id
INNER JOIN keywords ON keywords.id = (SELECT id FROM keywords WHERE keywords.nct_id = s.nct_id AND keywords.downcase_name SIMILAR TO $2 AND keywords.downcase_name SIMILAR TO $5 AND keywords.downcase_name SIMILAR TO $6 AND keywords.downcase_name SIMILAR TO $8 LIMIT 1)
WHERE s.overall_status NOT SIMILAR TO '(Suspended|Withheld|Completed|No longer available|Withdrawn|Terminated)' AND s.phase SIMILAR TO $4 LIMIT 20 OFFSET ($3 - 1) * 20`;
db.map(query, [country + '%','%' + type + '%',page, '%' + phase + '%', '%' + adjuvant + '%', '%' + metastatic + '%', '%' + city + '%', '%' + gene + '%'], a => a.json)
.then(data => {
res.json({data: data, page: page, status: 200});
})
.catch(error => {
console.log(error);
res.status(500).send('Error occured');
});
});