Problem/Motivation
The module allows for direct and reverse selection between entities that reference each-other.
When you start joining multiple entity types, the indexes becomes important part (especially in views).
So when you have the direct link, it's OK, as the primary key is used for the lookup.
The problems comes with the views relationship called "Referencing entity". It is making a join based on the following columns:
- deleted (0)
- entity_type - string
- *_target_id - referenced entity ID.
In this case the current schema on MySQL 5.5 (default for Ubuntu 14.04) can use only the 'deleted' field index. In most cases this is non-optimal, as it is very close to a full table in length.
In my case, the views query was covering ~1200 rows, when doing the join. Rows estimate taken from explain. The index used was delete, not the *_target_id one.
Proposed resolution
I managed to fix this with adding an index on deleted, entity_type, *_target_id fields, so views can be optimized for reverse queries.
Note that the columns order is important. I've tested with *_target_id first, and the query optimizer was picking the deleted index again.
I've tested locally the same query and it resulted in evaluation of 5 rows (based on explain), and also using the new index, instead of the deleted generic one.
Remaining tasks
Discussion, patch, etc.
User interface changes
None.
API changes
None.
Data model changes
New index in the entity reference fields' tables.
Comment | File | Size | Author |
---|---|---|---|
#2 | entityreference-missing-index-referencing-entity-relation-2827782-D7-2.patch | 1.77 KB | ndobromirov |
Comments
Comment #2
ndobromirov CreditAttribution: ndobromirov commentedHere is a patch with an update hook that fixed this for me for existing fields.
I've also tried to add the index on field's schema hook, but it did not worked, because of errors like this during node creation:
Code attempting to do this is available in the patch (but commented out).
TODOs:
1. Fix the field's schema to add the index on table creation. So it is still in needs work.
Comment #3
ndobromirov CreditAttribution: ndobromirov commentedI've tracked this to core, please correct me if I'm wrong, but it seems to be impossible to define indexes based on field API columns and field level columns (like it's in this issue's case).
The issue is coming from the way hook_field_schema API is implemented and used. There are no later hooks and all indexes defined in it are expected to work only on it's columns (as you can see from the error in the prefixing).
This is taken out from hook_field_schema($field) docks so it's confirming my suspensions.
Any options to move this forward will be appreciated...
Comment #4
ndobromirov CreditAttribution: ndobromirov commentedAdded a reference to issue against D8 core, as this index is missing there also.
Both views and entity-reference modules are part of it.