To improve performance, we should implement custom storage_schema handlers for certain entities. This allows us to add indexes for fields in the entity's shared table schema.
Entities and indexes
Note: all entityreference values are already indexed.
Coupon
- code
Order
- order_number
Payment
- remote_id
Payment method
- remote_id
Product variation
- sku
Original summary
Since the SKU acts as an external id it soulds be indexed in database for better import performance.
| Comment | File | Size | Author |
|---|---|---|---|
| #35 | Drupal-database-update.png | 127.45 KB | mahtabalam |
| #31 | Status_report___CS_Payment.png | 111.35 KB | joelpittet |
| #26 | 2907367.patch | 12.74 KB | eiriksm |
| #26 | interdiff.txt | 947 bytes | eiriksm |
| #24 | 2907367.patch | 12.73 KB | eiriksm |
Comments
Comment #2
bojanz commentedSame with the coupon code and payment remote ID. We need to look at our storage classes, see what we're loading by, ensure indexes.
Comment #3
mglamanReviewing
Comment #4
mglamanReviewing \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::getSharedTableFieldSchema
Indexes are set if the field schema has indexes.
Currently, we have indexes on the product_id, type, and UID. That is because
\Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::schemacontainsIn
\Drupal\Core\Field\Plugin\Field\FieldType\StringItem::schemathere are no index definitions.I believe the way we work around this is to implement a new
storage_schemahandler, like\Drupal\node\NodeStorageSchema. This allows us to arbitrarily added index. See the following exampleComment #5
mglamanComment #6
mglamanComment #7
mglamanComment #8
mglamanInitial patch. No idea what kind of upgrade path we need to do.
PR: https://github.com/drupalcommerce/commerce/pull/794
Comment #9
mglamanComment #10
mglamanPicking this up, again, finally!
Comment #11
mglamanRerolled against HEAD, need to test the upgrade still.
Comment #12
mglamanSplit the updates into each module, as the schema change wasn't being run due to clearing entity definitions.
EDIT: Updates are not applying, properly. I am trying to to determine why \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::requiresEntityStorageSchemaChanges always returns false.
Comment #13
mglamanOkay! This fixes our problem. There is a limitation in core where the storage schema handler exits early and does not generate indexes unless there is a change in ability to translate, revisions handling, or a field column change.
Comment #14
eiriksmLooks promising, and on testing. Going to do a full check on our enormous database tomorrow, where we already have an index on sku. Also we limited sku to 32 characters, but that should probably not be an issue.
Comment #15
mglamaneiriksm thanks so much! I know you've got quite the database which means it will take some time :) but I want to make sure the upgrade path doesn't break on your site.
Comment #16
bojanz commentedPatch looks good to me.
Let's open that issue before we commit the patch :)
EDIT: I tried to investigate the issue myself, but wasn't sure what's going on.
Assuming that this is FALSE:
but the method has:
and that || should allow for indexes to change even if the shared table structure didn't, no?
Comment #17
eiriksmHey. We have a problem running this update. It is of course mostly our own fault, since we did some manual adjustments to the tables.
Here is the error message:
And here is the table (although crashed a couple of times in an update):
It might very well be because we did not alter the schema after we changed the length of the sku field though, so testing that now.
Comment #18
eiriksmCan confirm it works if I alter the schema definition to also be correct.
Of course now I have two indexes on SKU, but that seems like something one can manage :)
Comment #19
mglamanFollowing up to #16
\Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::requiresEntityStorageSchemaChanges
The first check
hasSharedTableStructureChangewil alwas return false, since we did not change any of the entities in regards to the ability to be revisionable, translatable, or change their table names.The second check fails because
\Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::getEntitySchemadoes not include indexes. It does not add indexes inprocessDataTableorprocessBaseTable$schema[$published_field_table]['indexes'][$this->getEntityIndexName($entity_type, $key)] = $columns;getEntitySchemaDatafalls short, as well. It ends up invoking \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::getFieldSchemaData. This only concerns itself with indexes defined on the field type itself, which is why entity references have indexes properly.So, unless these fields were their custom field types with specified indexes, there is no way for Drupal core to detect additional indices not defined within the field type.
Comment #20
mglamanLinking to the related core issue we will comment in the code doc. I just downloaded my IRCCloud logs of the Drupal Slack to see if I can find my conversation with berdir.
EDIT Found it!
Comment #21
mglamanRerolled against HEAD and includes link to the core issue.
Comment #22
alanhdev commentedWe've been seeing various database-related performance issues and this patch addresses a specific one we have seen caused by the lack of an index on commerce_order.order_number.
I've reviewed the patch and the indexes included are applied correctly.
Comment #23
alanhdev commentedMoving back to status Needs Work as we are seeing 'Mismatched entity and/or field definitions' warnings after applying the patch and running updates:
Comment #24
eiriksmUpdated patch
Comment #26
eiriksmComment #27
mglamanLooks good, I'll get this committed. I trust @eiriksm has put it through the paces for their fairly large site :)
Comment #29
mglaman🥳 Committed! Yay for performance.
Comment #31
joelpittet@mglaman, we ran into this when testing out some stuff, thought you should know, maybe an update hook is needed?
Comment #32
joelpittetHere's the docs on the adding index in your update hook:
https://www.drupal.org/docs/drupal-apis/update-api/updating-database-sch...
Comment #33
joelpittetAh sorry, should have searched #3005447: Adding an index to an entity's schema is not detected as a change in onEntityTypeUpdate is addressing thisI'll create a follow-upComment #34
berdirThis doesn't seem right. If you add an index on a field, then the correct thing to do is call updateFieldStorageSchema() and that should add the index automatically. Don't just update the entity type.
Comment #35
mahtabalamAfter updating Drupal commerce I get below mention unexpected error.
When I run update.php there were 11 updates. Image attached Drupal-database-update.png