Problem/Motivation
Full disclosure, this summary was written by AI.
linkchecker_link is queried by parent_entity_type_id + parent_entity_id on every entity save but neither column is indexed. The module ships a dedicated storage-schema handler (LinkCheckerLinkStorageSchema) that indexes method, code, fail_count, last_check — the checking/reporting columns — but omits the two columns used by the extraction/cleanup path that runs on save (LinkCleanUp.php, LinkExtractorService.php, LinkCheckerStorage.php). So each lookup is a full scan, and the cost grows with the size of linkchecker_link and the number of child entities per host entity (e.g. a node with many Paragraphs — each paragraph is its own parent entity -> its own lookup).
Steps to reproduce
1. Large linkchecker_link table (~104,500 rows).
2. A node built from many Paragraphs (169 nested paragraphs).
3. Save the node → one unindexed lookup per parent entity; on a stack with a gateway/PHP timeout the request errors out while the write eventually completes.
Measured impact
Node with 169 paragraphs, 104,545 rows (D10.6.9 / PHP 8.2 / MariaDB 10.3):
| | Save wall | DB time | linkchecker query (~430 calls) |
| ------------------------ | --------- | ------- | ------------------------------ |
| No index | **71.1s** | 68.8s | 49.1s |
| With parent-entity index | **2.8s** | 0.8s | 0.08s |
EXPLAIN goes from ~100K rows examined to a 1-row range scan.
Proposed resolution
Add to LinkCheckerLinkStorageSchema::getEntitySchema() (varchar needs a prefix length):
'parent_entity' => [['parent_entity_type_id', 32], 'parent_entity_id'],
plus a hook_update_N - to create the index on existing installs.
| Comment | File | Size | Author |
|---|---|---|---|
| parent-entity-index.patch | 2.17 KB | bburg |
Comments
Comment #2
bburg