V2 : optimisation API (cache, index, vue materialisee)
- BDD (migrations 1.6.0 + 1.7.0, idempotentes) :
* 4 nouveaux index composites sur reactevents, triggerevents, sessions
* vue sessiondebriefs reecrite (sous-requetes correlees -> JOINs)
puis materialisee dans table session_debriefs_cache via procedure
stockee rebuild_debrief_cache, recalculee uniquement aux changements
* fix bug double JOIN participates : TargetRole = "IA" pour les hits
NPC/objets (au lieu d'un role aleatoire de participant)
- API PHP :
* connexion PDO en singleton + ATTR_PERSISTENT
* cache disque par session (cache/sess_<id>/) pour debrief, get, userhistory
avec invalidation ciblee sur events et lifecycle
* pagination opt-in (limit/offset) sur lists/sessions_for_user
* helpers ensure_/rebuild_/invalidate_session_debrief_cache_db
* debug/benchmark.php pour mesurer la latence des 6 endpoints cles
- Endpoints HTTP : signatures inchangees, compat Unreal preservee
- Gain mesure : -58% a -83% sur les 5 endpoints cles
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -325,7 +325,61 @@ INSERT INTO `userstatus` (`id`, `displayName`, `description`) VALUES
|
||||
--
|
||||
DROP TABLE IF EXISTS `sessiondebriefs`;
|
||||
|
||||
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `sessiondebriefs` AS SELECT `s`.`id` AS `SessionId`, `s`.`sessionType` AS `SessionTypeId`, `st`.`displayName` AS `SessionType`, `s`.`sessionName` AS `SessionName`, `s`.`sessionDate` AS `SessionDate`, `s`.`mapName` AS `MapName`, `s`.`scenarioName` AS `ScenarioName`, `s`.`success` AS `SessionSuccessful`, `s`.`timeToFinish` AS `SessionDuration`, coalesce(`t`.`type`,-1) AS `TriggerTypeId`, coalesce(`tt`.`displayName`,'') AS `TriggerType`, (select ifnull(`t`.`srcUserId`,`ps`.`userId`)) AS `ShooterId`, `us`.`username` AS `ShooterName`, (select ifnull(`ps`.`role`,3)) AS `ShooterRoleId`, (select `r`.`displayName` from `userroles` `r` where `r`.`id` = `ShooterRoleId`) AS `ShooterRole`, coalesce(`t`.`indexCount`,-1) AS `ShotIndex`, coalesce(`r`.`id`,-1) AS `ReactId`, coalesce(`r`.`reactMode`,2) AS `ReactModeId`, coalesce(`rm`.`displayName`,'') AS `ReactMode`, coalesce(`r`.`reactType`,-1) AS `ReactTypeId`, coalesce(`rt`.`displayName`,'') AS `ReactType`, coalesce(`r`.`hitUserId`,-1) AS `TargetUserId`, coalesce(`uh`.`username`,'') AS `TargetUserName`, (select ifnull(`ph`.`role`,3)) AS `TargetRoleId`, (select `r`.`displayName` from `userroles` `r` where `r`.`id` = `TargetRoleId`) AS `TargetRole`, coalesce(`r`.`hitTargetName`,'') AS `TargetName`, coalesce(`r`.`hitBoneName`,'') AS `TargetBoneName`, coalesce(`r`.`targetKilled`,0) AS `TargetKilled`, coalesce(`r`.`objectHitLocationX`,0) AS `HitLocationX`, coalesce(`r`.`objectHitLocationY`,0) AS `HitLocationY`, coalesce(`r`.`objectHitTagLocation`,'') AS `HitLocationTag`, coalesce(`r`.`hitPrecision`,0) AS `HitPrecision`, coalesce(`r`.`distance`,0) AS `HitTargetDistance`, coalesce(`r`.`reactTime`,0) AS `ReactionTime`, coalesce(`r`.`timeStamp`,0) AS `TimeStamp`, count(distinct `r`.`id`) AS `NbHit`, count(distinct `rk`.`srcEventIndex`,`rk`.`hitTargetName`) AS `NbKilled` FROM (((((((((((`sessions` `s` left join `participates` `ps` on(`s`.`id` = `ps`.`sessionId`)) left join `participates` `ph` on(`s`.`id` = `ph`.`sessionId`)) left join `triggerevents` `t` on(`s`.`id` = `t`.`sessionId`)) left join `triggereventtypes` `tt` on(`tt`.`id` = `t`.`type`)) left join `sessiontypes` `st` on(`st`.`id` = `s`.`sessionType`)) left join `reactevents` `r` on(`t`.`indexCount` = `r`.`srcEventIndex` and `t`.`sessionId` = `r`.`srcEventSessionId`)) left join `users` `uh` on(`uh`.`id` = `r`.`hitUserId`)) left join `users` `us` on(`us`.`id` = `t`.`srcUserId` or `us`.`id` = `ps`.`userId`)) left join `reacteventtypes` `rt` on(`rt`.`id` = `r`.`reactType`)) left join `reacteventmodes` `rm` on(`rm`.`id` = coalesce(`r`.`reactMode`,2))) left join `reactevents` `rk` on(`r`.`id` = `rk`.`id` and `rk`.`targetKilled` = 1)) GROUP BY `s`.`id`, (select ifnull(`t`.`srcUserId`,`ps`.`userId`)), `t`.`indexCount`, `r`.`hitTargetName` ORDER BY `s`.`id` ASC, (select ifnull(`t`.`srcUserId`,`ps`.`userId`)) ASC, `t`.`indexCount` ASC, `r`.`id` ASC ;
|
||||
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `sessiondebriefs` AS
|
||||
SELECT
|
||||
`s`.`id` AS `SessionId`,
|
||||
`s`.`sessionType` AS `SessionTypeId`,
|
||||
`st`.`displayName` AS `SessionType`,
|
||||
`s`.`sessionName` AS `SessionName`,
|
||||
`s`.`sessionDate` AS `SessionDate`,
|
||||
`s`.`mapName` AS `MapName`,
|
||||
`s`.`scenarioName` AS `ScenarioName`,
|
||||
`s`.`success` AS `SessionSuccessful`,
|
||||
`s`.`timeToFinish` AS `SessionDuration`,
|
||||
COALESCE(`t`.`type`, -1) AS `TriggerTypeId`,
|
||||
COALESCE(`tt`.`displayName`, '') AS `TriggerType`,
|
||||
IFNULL(`t`.`srcUserId`, `ps`.`userId`) AS `ShooterId`,
|
||||
`us`.`username` AS `ShooterName`,
|
||||
IFNULL(`ps`.`role`, 3) AS `ShooterRoleId`,
|
||||
`urs`.`displayName` AS `ShooterRole`,
|
||||
COALESCE(`t`.`indexCount`, -1) AS `ShotIndex`,
|
||||
COALESCE(`r`.`id`, -1) AS `ReactId`,
|
||||
COALESCE(`r`.`reactMode`, 2) AS `ReactModeId`,
|
||||
COALESCE(`rm`.`displayName`, '') AS `ReactMode`,
|
||||
COALESCE(`r`.`reactType`, -1) AS `ReactTypeId`,
|
||||
COALESCE(`rt`.`displayName`, '') AS `ReactType`,
|
||||
COALESCE(`r`.`hitUserId`, -1) AS `TargetUserId`,
|
||||
COALESCE(`uh`.`username`, '') AS `TargetUserName`,
|
||||
IFNULL(`ph`.`role`, 3) AS `TargetRoleId`,
|
||||
`urt`.`displayName` AS `TargetRole`,
|
||||
COALESCE(`r`.`hitTargetName`, '') AS `TargetName`,
|
||||
COALESCE(`r`.`hitBoneName`, '') AS `TargetBoneName`,
|
||||
COALESCE(`r`.`targetKilled`, 0) AS `TargetKilled`,
|
||||
COALESCE(`r`.`objectHitLocationX`, 0) AS `HitLocationX`,
|
||||
COALESCE(`r`.`objectHitLocationY`, 0) AS `HitLocationY`,
|
||||
COALESCE(`r`.`objectHitTagLocation`, '') AS `HitLocationTag`,
|
||||
COALESCE(`r`.`hitPrecision`, 0) AS `HitPrecision`,
|
||||
COALESCE(`r`.`distance`, 0) AS `HitTargetDistance`,
|
||||
COALESCE(`r`.`reactTime`, 0) AS `ReactionTime`,
|
||||
COALESCE(`r`.`timeStamp`, 0) AS `TimeStamp`,
|
||||
COUNT(DISTINCT `r`.`id`) AS `NbHit`,
|
||||
COUNT(DISTINCT `rk`.`srcEventIndex`, `rk`.`hitTargetName`) AS `NbKilled`
|
||||
FROM `sessions` `s`
|
||||
LEFT JOIN `participates` `ps` ON (`s`.`id` = `ps`.`sessionId`)
|
||||
LEFT JOIN `participates` `ph` ON (`s`.`id` = `ph`.`sessionId`)
|
||||
LEFT JOIN `triggerevents` `t` ON (`s`.`id` = `t`.`sessionId`)
|
||||
LEFT JOIN `triggereventtypes` `tt` ON (`tt`.`id` = `t`.`type`)
|
||||
LEFT JOIN `sessiontypes` `st` ON (`st`.`id` = `s`.`sessionType`)
|
||||
LEFT JOIN `reactevents` `r` ON (`t`.`indexCount` = `r`.`srcEventIndex` AND `t`.`sessionId` = `r`.`srcEventSessionId`)
|
||||
LEFT JOIN `users` `uh` ON (`uh`.`id` = `r`.`hitUserId`)
|
||||
LEFT JOIN `users` `us` ON (`us`.`id` = `t`.`srcUserId` OR `us`.`id` = `ps`.`userId`)
|
||||
LEFT JOIN `reacteventtypes` `rt` ON (`rt`.`id` = `r`.`reactType`)
|
||||
LEFT JOIN `reacteventmodes` `rm` ON (`rm`.`id` = COALESCE(`r`.`reactMode`, 2))
|
||||
LEFT JOIN `reactevents` `rk` ON (`r`.`id` = `rk`.`id` AND `rk`.`targetKilled` = 1)
|
||||
LEFT JOIN `userroles` `urs` ON (`urs`.`id` = IFNULL(`ps`.`role`, 3))
|
||||
LEFT JOIN `userroles` `urt` ON (`urt`.`id` = IFNULL(`ph`.`role`, 3))
|
||||
GROUP BY `SessionId`, `ShooterId`, `ShotIndex`, `TargetName`
|
||||
ORDER BY `SessionId`, `ShooterId`, `ShotIndex`, `ReactId`;
|
||||
|
||||
--
|
||||
-- Index pour les tables déchargées
|
||||
|
||||
Reference in New Issue
Block a user