From 2e593ebceea5309f654c0b780e0b8414a6e5ff7b Mon Sep 17 00:00:00 2001 From: Steve Larson <9larsons@gmail.com> Date: Wed, 26 Jun 2024 16:29:02 -0500 Subject: [PATCH] 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. --- ...-12-08-20-add-posts-tags-post-tag-index.js | 26 +++++++++++++++++++ ...add-posts-type-status-updated-at-index.js} | 2 +- ghost/core/core/server/data/schema/schema.js | 7 +++-- .../unit/server/data/schema/integrity.test.js | 2 +- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-20-add-posts-tags-post-tag-index.js rename ghost/core/core/server/data/migrations/versions/5.87/{2024-06-20-17-02-15-add-posts-type-status-index.js => 2024-06-25-12-08-45-add-posts-type-status-updated-at-index.js} (93%) diff --git a/ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-20-add-posts-tags-post-tag-index.js b/ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-20-add-posts-tags-post-tag-index.js new file mode 100644 index 0000000000..4aa38673db --- /dev/null +++ b/ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-20-add-posts-tags-post-tag-index.js @@ -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; + } + } +); \ No newline at end of file diff --git a/ghost/core/core/server/data/migrations/versions/5.87/2024-06-20-17-02-15-add-posts-type-status-index.js b/ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-45-add-posts-type-status-updated-at-index.js similarity index 93% rename from ghost/core/core/server/data/migrations/versions/5.87/2024-06-20-17-02-15-add-posts-type-status-index.js rename to ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-45-add-posts-type-status-updated-at-index.js index 375725294f..2415fe1d44 100644 --- a/ghost/core/core/server/data/migrations/versions/5.87/2024-06-20-17-02-15-add-posts-type-status-index.js +++ b/ghost/core/core/server/data/migrations/versions/5.87/2024-06-25-12-08-45-add-posts-type-status-updated-at-index.js @@ -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']); \ No newline at end of file +module.exports = createAddIndexMigration('posts',['type','status','updated_at']); \ No newline at end of file diff --git a/ghost/core/core/server/data/schema/schema.js b/ghost/core/core/server/data/schema/schema.js index d63f74febf..f2e7052f8c 100644 --- a/ghost/core/core/server/data/schema/schema.js +++ b/ghost/core/core/server/data/schema/schema.js @@ -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}, diff --git a/ghost/core/test/unit/server/data/schema/integrity.test.js b/ghost/core/test/unit/server/data/schema/integrity.test.js index 9f6feb5d85..9e8ea29125 100644 --- a/ghost/core/test/unit/server/data/schema/integrity.test.js +++ b/ghost/core/test/unit/server/data/schema/integrity.test.js @@ -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';