From the discussion in #2447555: Unnecessary index on langcode and deleted column in dedicated field tables. (comments #3 and #4 over there), we miss two composite indexes on dedicated field tables :

- entity_id, deleted, langcode : for Views joins
- revision_id, deleted, delta, langcode: for SqlContentEntityStorage::loadFromDedicatedTables() in case of "load an older / not current revision"

Comments

yched’s picture

As a side note, we should really add comments in the code saying why each index is present (like "used by the query in Xxx::foo()"), this would save us having to dig in the code for who does which query each time we wonder if our indexes are right :-)

yched’s picture

Priority: Normal » Major

If our views joins are not indexed as they should, that probably qualifies at least as major :-)

yched’s picture

Regarding "add index on entity_id, deleted, langcode : for Views joins" :

We did a couple tests with @Berdir and @fgm :

- A typical Views joins looks like (here, a view with a filter on body field):

SELECT node_field_data.created AS node_field_data_created, node_field_data.nid AS nid
FROM node_field_data node_field_data
LEFT JOIN node__body node__body
ON node_field_data.nid = node__body.entity_id
AND node__body.deleted =  '0'
AND node__body.langcode = node_field_data.langcode
WHERE node_field_data.status =  '1'
AND node__body.body_value LIKE  ''ESCAPE  '\\'

This currently use the primary key ("entity_id, deleted, delta, langcode"). It has no use for the "delta" part, so it's mostly using the first two parts of the index.
Putting delta last in the primary key could be slightly better for this query, but the overall query perf is likely to be determined by the actual condition on the field value (and most notably whether the condition is on an indexed column or not - here, node__body.body_value is not indexed)

- The primary key is otherwise mostly used to index the "main entity load request" in SqlContentEntityStorage::loadFromDedicatedTables() - typically :

SELECT * FROM node__body 
WHERE entity_id IN ( [multiple entity ids] )
AND deleted = 0
AND langcode IN ( [the languages currently enabled] )
ORDER BY delta

The primary key is in that order (delta, langcode, rather than langcode, delta) for no good reason. It seems D7's #367595: Translatable fields simply pushed 'langcode' at the end of the existing primary key without caring too much...

From our tests, switching the order in the primary key doesn't make much difference, typically because selecting a bunch of entity_ids reduced the number of rows drastically enough that additionally using the index for the low-cardinality delta and langcode columns is not that critical.

yched’s picture

Based on the above, our proposal would be : don't add a new index for Views, but just reorder the primary key to "entity_id, deleted, langcode, delta" :

- it makes no difference for the "entity load" case
- it is slightly better for Views joins (at least theoretically, in practice probably a wash)
- it is more consistent with our runtime data model (entity, field, langcode, delta)

yched’s picture

Then, about the second index mentioned in the IS ("revision_id, deleted, delta, langcode", for in case of "load an older / not current entity revision") :

The query in that case is :

SELECT * FROM node_revision__body 
WHERE revision_id IN ( [multiple revision ids] )
AND deleted = 0
AND langcode IN ( [the languages currently enabled] )
ORDER BY delta

- the index is only needed on the revision table
- by the same reasoning, and for consistency with the above, it could be "revision_id, deleted, langcode, delta" (instead of the proposed "... delta, langcode")

The primary key on the revision table is "*entity_id*, revision_id, deleted, delta, langcode" - and I don't think we can actually add a condition on entity_ids in the query above, so the primary key doesn't help here.
So we would need to add a new index on "revision_id, deleted, langcode, delta" in addition to the current primary key.

But : what if we removed entity_id from the primary key in the revision table ? Then we could use that primary key for the "load old entity revision" query, just like we use the primary key of the "current revision table" for the "load current entity revision" query...

Looking at what is done of shared / base fields table
node_field_data has a primary key of "nid, langcode"
node_field_revision has a primary key of "vid, langcode"
so that would be consistent ? :-)

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

pameeela’s picture

@yched do you think this issue is still relevant, and if so, still major? If so it would be great to get an issue summary update with the current state and perhaps a proposal for how to address it? Asking a lot, I know but this was currently the last major in the whole queue as far as latest update!

Berdir’s picture

@yched isn't active anymore, but he outlined the results of our tests and discussions very well, so I think anyone could try to update the issue summary based on that.

Implementing it, specifically an update path might be a challenge though.

Also, for the revision tables, we should also look at the performance of saving an entity, with a delete and then insert.

pameeela’s picture

johnwebdev’s picture

Priority: Major » Normal

Given the outline in #4

it is slightly better for Views joins (at least theoretically, in practice probably a wash)

Given the improvement just seems to be slightly better theoretically, I don't think this issues needs to be major anymore, feel free to disagree and promote it back.

pameeela’s picture

Issue tags: +Bug Smash Initiative

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.