Follows #3615284: The basket pointer is re-read from the tempstore on every question asked of the cart, so one place click costs four identical key/value reads, which read the basket pointer once per request instead of once per question and took a recurring place click from 25 queries to 22. This records what the remaining 22 are, so the analysis does not have to be done again, and names the four that can go without changing any guarantee.
How to see it
PlaceMapPerformanceTest, the recurring-click scenario: a click that lands in a basket already opened, which is what a booker choosing six places pays five times over. The list comes from PerformanceData::getQueries() over that measured window.
Where the 22 go
- 3, core auth for an authenticated POST: sessions, users_field_data, user__roles.
- 1, the basket pointer, already down from four in #3615284: The basket pointer is re-read from the tempstore on every question asked of the cart, so one place click costs four identical key/value reads.
- 3, SAVEPOINT plus the booking INSERT plus RELEASE.
- 2, the cachetags select and update that publish the hold.
- 1, the slot row lock.
- 3, the availability re-check under that lock, which is the binding answer.
- 3, the same trio asked before the lock, optimistically.
- 6, the rest: the order's lines read either side of the write, the configuration section, and a reload of the booking just inserted.
The four worth removing
- The reload of the just-inserted booking. The controller already holds the saved entity.
- The second read of the order's lines after the write. The new line can be appended in PHP to the set already read, rather than asking again.
- The second read of yoyaku_slot_tariff under the lock. The tariff list is not the contended value; the consumed quota is, and that one is correctly re-read FOR UPDATE.
- The configuration section, read on every click. It is structural, it rarely changes, and it belongs in a cache bin keyed by configuration id with the entity's own cache tag.
Together those take a click from 22 to about 18, with no change to locking, ordering or any promise the engine makes.
Two that look like savings and are decisions
The optimistic trio asked before the lock is three more queries, and dropping it would reach about 15. It exists so that a click on a place somebody else already took can be answered without queueing on the row lock, and a busy hall is exactly when that matters. It should not move on a query count alone: measure contention first.
The first click of a visit costs 49 rather than 22, and a good part of that is a separate HTTP request to /session/token before the POST can be made. That is a whole round trip the visitor waits through, and worth more than several queries. The page could carry the token instead, but core serves it apart precisely so the page itself stays cacheable, so this is a trade rather than an oversight.
Why postponed
Twenty-two indexed point lookups on a write that takes a row lock is not obviously wrong, and the repetition that was plainly waste has already gone. Before removing more, it is worth measuring where the milliseconds of a click actually are: the lock wait and the token round trip may well dominate all 22 queries together. The performance test added in #3615284: The basket pointer is re-read from the tempstore on every question asked of the cart, so one place click costs four identical key/value reads pins the current numbers, so any of this work will show up as the number moving.
Comments