Improved performance fetching posts (#20460)

ref https://linear.app/tryghost/issue/ONC-111
- added composite index to posts_tags for post_id,tag_id for faster
lookup
- added composite index to posts for updated_at; this is commonly used
by get helpers on the front end to display data like the latest posts

In testing, this provided a very dramatic improvement for simple get
helper requests like 'filter="id:-{{post.id}}+tag:sampleTag" limit="3"'
which are by default sorted by updated_at desc. I'm not entirely clear
why when sorting by published_at we do not need a composite index - so
far it doesn't seem to be necessary. This should cover the primary cases
for get helpers - the latest posts with a given tag or set of tags.
This commit is contained in:
Steve Larson 2024-06-26 16:29:02 -05:00 committed by GitHub
parent dfc27b02c8
commit 2e593ebcee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 33 additions and 4 deletions

View File

@ -0,0 +1,26 @@
const logging = require('@tryghost/logging');
const {createNonTransactionalMigration} = require('../../utils');
const {addIndex, dropIndex} = require('../../../schema/commands');
module.exports = createNonTransactionalMigration(
async function up(knex) {
await addIndex('posts_tags', ['post_id', 'tag_id'], knex);
},
async function down(knex) {
try {
await dropIndex('posts_tags', ['post_id', 'tag_id'], knex);
} catch (err) {
if (err.code === 'ER_DROP_INDEX_FK') {
logging.error({
message: 'Error dropping index over posts_tags(post_id, tag_id), re-adding index for post_id'
});
await addIndex('posts_tags', ['post_id'], knex);
await dropIndex('posts_tags', ['post_id', 'tag_id'], knex);
return;
}
throw err;
}
}
);

View File

@ -1,4 +1,4 @@
// For information on writing migrations, see https://www.notion.so/ghost/Database-migrations-eb5b78c435d741d2b34a582d57c24253
const {createAddIndexMigration} = require('../../utils');
module.exports = createAddIndexMigration('posts',['type','status']);
module.exports = createAddIndexMigration('posts',['type','status','updated_at']);

View File

@ -94,7 +94,7 @@ module.exports = {
newsletter_id: {type: 'string', maxlength: 24, nullable: true, references: 'newsletters.id'},
show_title_and_feature_image: {type: 'boolean', nullable: false, defaultTo: true},
'@@INDEXES@@': [
['type','status']
['type','status','updated_at']
],
'@@UNIQUE_CONSTRAINTS@@': [
['slug', 'type']
@ -298,7 +298,10 @@ module.exports = {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
post_id: {type: 'string', maxlength: 24, nullable: false, references: 'posts.id'},
tag_id: {type: 'string', maxlength: 24, nullable: false, references: 'tags.id'},
sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0}
sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0},
'@@INDEXES@@': [
['post_id','tag_id']
]
},
invites: {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},

View File

@ -35,7 +35,7 @@ const validateRouteSettings = require('../../../../../core/server/services/route
*/
describe('DB version integrity', function () {
// Only these variables should need updating
const currentSchemaHash = '45c8072332176e0fe5a4fdff58fb2113';
const currentSchemaHash = 'ce97eff9bf1b3c215fed1271f9275f83';
const currentFixturesHash = 'a489d615989eab1023d4b8af0ecee7fd';
const currentSettingsHash = '5c957ceb48c4878767d7d3db484c592d';
const currentRoutesHash = '3d180d52c663d173a6be791ef411ed01';