perf(clickhouse): P3 — view_ip_recurrence avec filtre TTL + supprimer FINAL

view_ip_recurrence :
  Ajout de WHERE detected_at >= now() - INTERVAL 30 DAY
  → Avec PARTITION BY (P1), ClickHouse élagage les partitions hors de cette
    plage avant même de lire les données. La vue ne scanne que les partitions
    actives (au lieu des 30 partitions journalières complètes).
  → ORDER BY (src_ip) garantit que le GROUP BY src_ip lit des données
    contiguës (aucune réorganisation mémoire).

rotation.py — supprimer FINAL sur ml_detected_anomalies :
  FINAL force une déduplication complète du ReplacingMergeTree en mémoire
  (équivalent à un DISTINCT sur toute la table) — une des opérations les plus
  coûteuses dans ClickHouse.
  Fix : remplacer le sous-SELECT FINAL par view_ip_recurrence (déjà aggrégée
  par src_ip, retourne recurrence directement sans FINAL).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
toto
2026-04-07 22:33:29 +02:00
parent 2bfb4b7282
commit ecceb04174
2 changed files with 21 additions and 8 deletions

View File

@ -112,15 +112,27 @@ SETTINGS
-- -----------------------------------------------------------------------------
-- view_ip_recurrence — recurrence aggregation over ml_detected_anomalies
-- view_ip_recurrence — récurrence des détections par IP
--
-- Agrège ml_detected_anomalies (ORDER BY src_ip) pour obtenir le profil
-- de récurrence de chaque IP détectée.
--
-- Optimisation : avec PARTITION BY toYYYYMMDD(detected_at) (ajouté en P1),
-- chaque GROUP BY src_ip bénéficie de l'élagage de partitions si la vue est
-- filtrée par date en amont (les routes filtrent généralement sur 30 jours max).
-- Le ORDER BY (src_ip) garantit que le GROUP BY src_ip lit des données
-- contiguës en mémoire (co-localisation des lignes d'une même IP).
-- -----------------------------------------------------------------------------
CREATE OR REPLACE VIEW ja4_processing.view_ip_recurrence AS
SELECT
src_ip,
count() AS recurrence,
min(detected_at) AS first_seen,
max(detected_at) AS last_seen,
min(anomaly_score) AS worst_score,
count() AS recurrence,
min(detected_at) AS first_seen,
max(detected_at) AS last_seen,
min(anomaly_score) AS worst_score,
argMin(threat_level, anomaly_score) AS worst_threat_level
FROM ja4_processing.ml_detected_anomalies
-- Filtre temporel aligné sur le TTL de la table (30 jours)
-- Évite de scanner les partitions expirées non encore supprimées par le TTL
WHERE detected_at >= now() - INTERVAL 30 DAY
GROUP BY src_ip;