Index processing_status by project and by chunk - #1012
Merged
Conversation
processing_status is an event log of three million rows keyed by conversation. Directus resolves it as a relation on every project and every chunk read, and neither column had an index, so each read was a sequential scan of the whole table. Set is_indexed on project_id and conversation_chunk_id through the Directus API on a local instance and pulled the snapshot, so a schema push creates the same indexes with the names Directus expects.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
processing_status is an event log (about three million rows in production) keyed by conversation. Directus resolves it as a relation whenever a project or a conversation chunk is read, and neither
project_idnorconversation_chunk_idhad an index, so every such read scanned the whole table. Under load that put Directus's Postgres response time in the seconds and queued every dashboard request behind it.This sets
is_indexedon both fields the Directus way: flagged through the Directus API on a local instance, thensync.sh pull, so the snapshot matches what the environments carry and a future push never drops the indexes.Deployment note. Directus only recognises an index as
is_indexedwhen it is a single-column btree named<table>_<column>_index, and it reads that through its system cache. Both environments were indexed by hand during the incident, so before pushing this snapshot to an environment:create index concurrently processing_status_project_id_index on processing_status (project_id)and the same forconversation_chunk_id. Build under a temporary name and rename if a differently shaped index already holds the name.POST /utils/cache/clear?system=trueon that Directus, then confirmGET /fields/processing_status/project_idreportsis_indexed: true.sync.sh diffshows nothing for these fields and the push is a no-op.Both environments are already in that state: echo-next and production carry the two single-column indexes, their system caches were cleared, both report
is_indexed: true, and a read-onlysync.sh diffagainst production lists no change onprocessing_status. The push of this snapshot is a no-op for these two fields.Follow-ups, separate: stop resolving
processing_statuson project and chunk reads (the relation returns nothing useful), and stop the summariser writing a failure row per attempt.