Problem/Motivation

The published_at column has no database index.
Core indexes both created and changed on node_field_data, but the timestamp this module adds has none. A common use of the field is sorting content lists by publication date, and without an index every such view or query filesorts the whole table.

On our site (~14k nodes) a views query sorting by published_at takes ~20ms without the index and ~2ms with it.

Steps to reproduce

Create a view of published nodes sorted by "Published on" and EXPLAIN the query: no key is used for the sort, MySQL falls back to a filesort over all rows.

Minimal example on a table with ~15k nodes:

EXPLAIN ANALYZE SELECT nid, title, published_at FROM node_field_data
WHERE status = 1 ORDER BY published_at DESC LIMIT 10;

Without the index, all rows are read and filesorted, 10.4ms:

-> Sort: published_at DESC, limit input to 10 row(s) per chunk  (actual time=10.4 rows=10)
    -> Index lookup using node__status_type (status=1)  (actual time=0.06..9.6 rows=14028)

With the index, 12 rows are read in index order, 0.06ms:

-> Filter: (status = 1)  (actual time=0.04..0.05 rows=10)
    -> Index scan using node_field__published_at__value (reverse)  (actual time=0.03..0.05 rows=12)

Proposed resolution

Declare the index in PublicationDateItem::schema() so new installs get it automatically, and add an update hook for existing installs.

Remaining tasks

Review.

User interface changes

None.

API changes

None.

Data model changes

New index on the published_at column (node_field_data and node_field_revision).

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

herved created an issue. See original summary.

herved’s picture

Status: Active » Needs review
herved’s picture

Issue summary: View changes
Issue tags: +Performance

mably made their first commit to this issue’s fork.

mably’s picture

Thanks for this, the missing index is a good catch and the before/after numbers make the case well. I reviewed the MR and pushed a small follow-up commit (819da61) for one blocker.

In the update hook, publication_date_update_30001() was defined inside _publication_date_populate_database_field() rather than at the top level: it was indented one level, and the helper closing brace landed after it. Since hook_update_N is only discovered as a top-level function, the hook would never be registered, so existing sites would not get the index (only fresh installs would), and if that helper ever ran twice in one request PHP would fatal with "Cannot redeclare function". The follow-up moves the hook out to the top level; no logic change.

The rest looks right: the schema() addition indexes new installs on both node_field_data and node_field_revision, and the installation test confirms that path.

One gap remains: the test only exercises the fresh-install path (schema()), not the update hook, which is why the pipeline stayed green despite the above. It would be worth adding coverage that runs the update on an already-installed site and asserts the index appears, ideally on both MySQL and Postgres since the module supports both and an index-only updateFieldStorageDefinition change is occasionally missed.

mably’s picture

I rebased this branch onto 3.x and retargeted the MR to 3.x (the default branch), so the index lands where new work goes.

That also clears the phpstan warning noted above: it was failing behind allow_failure only on the 3.0.x base, from a deprecated NodeStorage::revisionIds() call in the installation test that 3.x already fixed in #3567175. After the rebase the diff is just the three index files, and phpstan is clean. The earlier follow-up moving publication_date_update_30001() to the top level is preserved in the rebased history.

  • mably committed cc9e0660 on 3.x authored by herved
    fix: #3610556 Missing index on the published_at column
    
    By: herved
    By:...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

herved’s picture

oh what a silly mistake I did there :) Thank you @mably, looks good now.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.