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:
@ -126,11 +126,12 @@ async def get_sophistication(limit: int = Query(50, ge=1, le=500)):
|
||||
FROM {settings.CLICKHOUSE_DB_PROCESSING}.view_host_ip_ja4_rotation
|
||||
) r
|
||||
LEFT JOIN (
|
||||
-- Utilise view_ip_recurrence (pré-agrégée) au lieu de ml_detected_anomalies FINAL
|
||||
-- FINAL force une déduplication complète du ReplacingMergeTree — très coûteux
|
||||
SELECT
|
||||
replaceRegexpAll(toString(src_ip), '^::ffff:', '') AS ip,
|
||||
count() AS recurrence
|
||||
FROM {settings.CLICKHOUSE_DB_PROCESSING}.ml_detected_anomalies FINAL
|
||||
GROUP BY ip
|
||||
recurrence
|
||||
FROM {settings.CLICKHOUSE_DB_PROCESSING}.view_ip_recurrence
|
||||
) rec ON r.ip = rec.ip
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user