Opened 3 years ago
Last modified 3 months ago
#59354 new defect (bug)
Unnecessary queries performed when updating a post without providing categories or tags
| Reported by: | johnbillion | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Posts, Post Types | Version: | |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: | performance |
Description
Given an existing post with at least some categories or tags present, updating the post via wp_update_post() (which calls wp_insert_post()) with data that does not include categories or tags, many unnecessary taxonomy-related database queries are performed. This slows down the saving significantly.
- If
$postarrdoesn't contain apost_categoryelement, there's no point in callingwp_set_post_categories(). - If
$postarrdoesn't contain atags_inputelement, there's no point in callingwp_set_post_tags()
Todo
- Need tests to verify the above is correct
- Need a list of queries that are performed before and after the change
To reproduce
- Publish a post with at least one category
- Update the post via:
<?php wp_insert_post( [ 'ID' => $id, 'post_content' => 'Hello, World!', ] );
- Observe that a significant number of unnecessary taxonomy queries are performed
Attachments (1)
Change History (5)
This ticket was mentioned in PR #6807 on WordPress/wordpress-develop by @LeonidasMilossis.
2 years ago
#1
- Keywords has-patch has-unit-tests added; needs-patch needs-unit-tests removed
#2
@
2 years ago
If
$postarrdoesn't contain atags_inputelement, there's no point in callingwp_set_post_tags().
We already do that in wp_insert_post() and indeed there's no extra queries unless we add 'tags_input' => $tag_id, in the wp_insert_post() params.
So, that part can probably be removed from the scope of this ticket.
The submitted PR adds a unit test that attests to that.
@
5 months ago
Patch for current trunk. Skips wp_set_post_categories() on update when post_category is not in $postarr, matching the existing tags_input guard. Includes unit test verifying fewer queries. All 62 wp_insert_post tests pass.
This ticket was mentioned in PR #11698 on WordPress/wordpress-develop by @motylanogha.
4 months ago
#3
wp_insert_post() always called wp_set_post_categories() on update, even when the caller did not pass post_category. The fallback then re-set the post's existing category list, which still goes through term-cache invalidation, term-relationship lookups, and counted toward the per-request query budget — a measurable regression for callers like REST API updates that change a single field.
This PR gates that call on either (a) it being a new post or (b) post_category being explicitly set in the args. The tags_input and tax_input paths were already correctly guarded.
Tests cover:
set_object_termsdoes not fire for thecategorytaxonomy on a parameterless update- Existing categories survive a parameterless update (regression guard)
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: https://core.trac.wordpress.org/ticket/59354