mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-03-29 19:22:02 -04:00
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>