Files
zoneminder/src
Nic Boet 637fe24f0a perf: skip Frames table scan during event playback unless debugging
Remove the FramesDuration subquery from the event metadata query in
EventStream::loadEventData(). Previously every playback initiation
ran:

  SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id

as an embedded subquery. Without a covering index on (EventId, Delta),
MySQL walks the EventId_idx to find matching rows then fetches each
table row to read the Delta column. For a 10-minute event in
Record/Mocord mode at 30fps with bulk_frame_interval=100, that is
~180 index lookups + row fetches. For alarm-heavy events where every
frame gets a DB row, it can reach thousands of row fetches. This
blocks playback start on every event view.

The FramesDuration value was only consumed by a Debug level 2 log
comparing it against Event Length. It was never used in any playback
computation, frame timing, seek logic, or client-facing output.
The frames_duration field has been removed from the EventData struct
entirely. The diagnostic query and its log are now colocated inside
a logLevel() >= DEBUG2 guard using a local variable.

Production impact: none. Default ZoneMinder log level is INFO (0).
DEBUG2 is only reached via explicit operator configuration
(Options > System > LOG_LEVEL_FILE or ZM_DBG_LEVEL env variable).
No production deployment runs at DEBUG2 as it generates thousands
of log lines per second per daemon. The subquery code path is
unreachable under default configuration. Operators who enable DEBUG2
get the same diagnostic output as before.

Theoretical gains on playback initiation per event:
- Eliminates 1 SQL subquery performing N row fetches from the
  critical path (N = Frames rows for the event)
- Record mode, 10min event: ~180 fewer row fetches
- Alarm-heavy 10min event: ~3,000-18,000 fewer row fetches
- Reduces MySQL buffer pool pressure from Frames page reads
- Reduces InnoDB row lock contention with concurrent frame INSERTs
  from active recording daemons hitting the same EventId range

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 16:18:51 -06:00
..
2026-01-31 12:43:03 -05:00
2026-01-29 18:50:42 -05:00
2026-02-05 09:07:22 -05:00
2026-01-31 12:43:03 -05:00