[{"data":1,"prerenderedAt":2658},["ShallowReactive",2],{"article-alternates":3,"article-\u002Ffr\u002Fdata\u002Farchitecture-table-cohort-retention-optimisation-production":13},{"i18nKey":4,"paths":5},"data-007-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fen\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fes\u002Fdata\u002Farquitectura-tabla-cohorte-escalando-analisis-retencion","\u002Ffr\u002Fdata\u002Farchitecture-table-cohort-retention-optimisation-production","\u002Fit\u002Fdata\u002Farchitettura-tabella-cohort-scalabilita-retention-analysis-production","\u002Fru\u002Fdata\u002Fcohort-table-architecture-scaling-retention","\u002Ftr\u002Fdata\u002Fcohort-tablo-mimarisi-retention-analizinin-productionda-olceklenmesi",{"_path":9,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":2652,"_id":2653,"_source":2654,"_file":2655,"_stem":2656,"_extension":2657},"data",false,"","Architecture de Table Cohort : Mise à l'Échelle de l'Analyse de Rétention en Production","Découvrez comment dimensionner les tables d'analyse de cohort en production avec materialized views, partitioning et optimisation des coûts de requête.","2026-07-28",[21,22,23,24,25],"analyse-cohort","bigquery","materialized-views","data-engineering","retention",9,"Roibase",{"type":29,"children":30,"toc":2636},"root",[31,48,55,83,510,523,528,535,540,623,643,677,682,688,707,896,901,943,948,1199,1219,1225,1235,1551,1556,1562,1579,1906,1910,1957,1970,1976,1996,2003,2029,2037,2062,2078,2084,2089,2142,2155,2182,2187,2204,2210,2223,2228,2264,2285,2291,2303,2326,2337,2384,2401,2412,2450,2467,2486,2492,2497,2505,2596,2613,2621,2630],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,46],{"type":37,"value":38},"text","Chaque organisation qui pratique l'analyse de rétention bute sur le même mur : les requêtes de cohort s'exécutent en 30 secondes en production, ou la facture BigQuery atteint 8 000 $ par mois. La requête ",{"type":32,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":37,"value":45},"GROUP BY user_id, cohort_week",{"type":37,"value":47}," qui fonctionnait proprement avec 100K utilisateurs en test s'effondre face à 50M d'utilisateurs et 2 ans de logs d'événements. La solution n'est pas simple — ajouter un index ou activer un cache ne suffira pas. Il faut redesigner l'architecture de la table entièrement pour la charge de travail retention.",{"type":32,"tag":49,"props":50,"children":52},"h2",{"id":51},"pourquoi-lanalyse-de-cohort-exige-une-architecture-différente",[53],{"type":37,"value":54},"Pourquoi l'Analyse de Cohort Exige une Architecture Différente",{"type":32,"tag":33,"props":56,"children":57},{},[58,60,66,68,74,75,81],{"type":37,"value":59},"Une table d'événements classique est construite sur ",{"type":32,"tag":40,"props":61,"children":63},{"className":62},[],[64],{"type":37,"value":65},"user_id",{"type":37,"value":67},", ",{"type":32,"tag":40,"props":69,"children":71},{"className":70},[],[72],{"type":37,"value":73},"event_time",{"type":37,"value":67},{"type":32,"tag":40,"props":76,"children":78},{"className":77},[],[79],{"type":37,"value":80},"event_name",{"type":37,"value":82},". Chaque requête de cohort scanne des milliards de lignes historiques, groupant les utilisateurs par la date du premier événement. Dans BigQuery, la requête ressemble à :",{"type":32,"tag":84,"props":85,"children":89},"pre",{"className":86,"code":87,"language":88,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","WITH cohorts AS (\n  SELECT user_id, DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week\n  FROM events\n  GROUP BY user_id\n),\nretention AS (\n  SELECT \n    c.cohort_week,\n    DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since_cohort,\n    COUNT(DISTINCT e.user_id) AS active_users\n  FROM cohorts c\n  JOIN events e ON c.user_id = e.user_id\n  GROUP BY 1, 2\n)\nSELECT * FROM retention ORDER BY 1, 2;\n","sql",[90],{"type":32,"tag":40,"props":91,"children":92},{"__ignoreMap":16},[93,121,165,179,193,202,219,232,256,324,369,382,432,454,463],{"type":32,"tag":94,"props":95,"children":98},"span",{"class":96,"line":97},"line",1,[99,105,111,116],{"type":32,"tag":94,"props":100,"children":102},{"style":101},"--shiki-default:#F97583",[103],{"type":37,"value":104},"WITH",{"type":32,"tag":94,"props":106,"children":108},{"style":107},"--shiki-default:#E1E4E8",[109],{"type":37,"value":110}," cohorts ",{"type":32,"tag":94,"props":112,"children":113},{"style":101},[114],{"type":37,"value":115},"AS",{"type":32,"tag":94,"props":117,"children":118},{"style":107},[119],{"type":37,"value":120}," (\n",{"type":32,"tag":94,"props":122,"children":124},{"class":96,"line":123},2,[125,130,135,141,146,151,156,160],{"type":32,"tag":94,"props":126,"children":127},{"style":101},[128],{"type":37,"value":129},"  SELECT",{"type":32,"tag":94,"props":131,"children":132},{"style":107},[133],{"type":37,"value":134}," user_id, DATE_TRUNC(",{"type":32,"tag":94,"props":136,"children":138},{"style":137},"--shiki-default:#79B8FF",[139],{"type":37,"value":140},"MIN",{"type":32,"tag":94,"props":142,"children":143},{"style":107},[144],{"type":37,"value":145},"(event_time), ",{"type":32,"tag":94,"props":147,"children":148},{"style":101},[149],{"type":37,"value":150},"WEEK",{"type":32,"tag":94,"props":152,"children":153},{"style":107},[154],{"type":37,"value":155},") ",{"type":32,"tag":94,"props":157,"children":158},{"style":101},[159],{"type":37,"value":115},{"type":32,"tag":94,"props":161,"children":162},{"style":107},[163],{"type":37,"value":164}," cohort_week\n",{"type":32,"tag":94,"props":166,"children":168},{"class":96,"line":167},3,[169,174],{"type":32,"tag":94,"props":170,"children":171},{"style":101},[172],{"type":37,"value":173},"  FROM",{"type":32,"tag":94,"props":175,"children":176},{"style":107},[177],{"type":37,"value":178}," events\n",{"type":32,"tag":94,"props":180,"children":182},{"class":96,"line":181},4,[183,188],{"type":32,"tag":94,"props":184,"children":185},{"style":101},[186],{"type":37,"value":187},"  GROUP BY",{"type":32,"tag":94,"props":189,"children":190},{"style":107},[191],{"type":37,"value":192}," user_id\n",{"type":32,"tag":94,"props":194,"children":196},{"class":96,"line":195},5,[197],{"type":32,"tag":94,"props":198,"children":199},{"style":107},[200],{"type":37,"value":201},"),\n",{"type":32,"tag":94,"props":203,"children":205},{"class":96,"line":204},6,[206,210,215],{"type":32,"tag":94,"props":207,"children":208},{"style":101},[209],{"type":37,"value":25},{"type":32,"tag":94,"props":211,"children":212},{"style":101},[213],{"type":37,"value":214}," AS",{"type":32,"tag":94,"props":216,"children":217},{"style":107},[218],{"type":37,"value":120},{"type":32,"tag":94,"props":220,"children":222},{"class":96,"line":221},7,[223,227],{"type":32,"tag":94,"props":224,"children":225},{"style":101},[226],{"type":37,"value":129},{"type":32,"tag":94,"props":228,"children":229},{"style":107},[230],{"type":37,"value":231}," \n",{"type":32,"tag":94,"props":233,"children":235},{"class":96,"line":234},8,[236,241,246,251],{"type":32,"tag":94,"props":237,"children":238},{"style":137},[239],{"type":37,"value":240},"    c",{"type":32,"tag":94,"props":242,"children":243},{"style":107},[244],{"type":37,"value":245},".",{"type":32,"tag":94,"props":247,"children":248},{"style":137},[249],{"type":37,"value":250},"cohort_week",{"type":32,"tag":94,"props":252,"children":253},{"style":107},[254],{"type":37,"value":255},",\n",{"type":32,"tag":94,"props":257,"children":258},{"class":96,"line":26},[259,264,269,273,277,281,285,290,295,299,303,307,311,315,319],{"type":32,"tag":94,"props":260,"children":261},{"style":107},[262],{"type":37,"value":263},"    DATE_DIFF(DATE_TRUNC(",{"type":32,"tag":94,"props":265,"children":266},{"style":137},[267],{"type":37,"value":268},"e",{"type":32,"tag":94,"props":270,"children":271},{"style":107},[272],{"type":37,"value":245},{"type":32,"tag":94,"props":274,"children":275},{"style":137},[276],{"type":37,"value":73},{"type":32,"tag":94,"props":278,"children":279},{"style":107},[280],{"type":37,"value":67},{"type":32,"tag":94,"props":282,"children":283},{"style":101},[284],{"type":37,"value":150},{"type":32,"tag":94,"props":286,"children":287},{"style":107},[288],{"type":37,"value":289},"), ",{"type":32,"tag":94,"props":291,"children":292},{"style":137},[293],{"type":37,"value":294},"c",{"type":32,"tag":94,"props":296,"children":297},{"style":107},[298],{"type":37,"value":245},{"type":32,"tag":94,"props":300,"children":301},{"style":137},[302],{"type":37,"value":250},{"type":32,"tag":94,"props":304,"children":305},{"style":107},[306],{"type":37,"value":67},{"type":32,"tag":94,"props":308,"children":309},{"style":101},[310],{"type":37,"value":150},{"type":32,"tag":94,"props":312,"children":313},{"style":107},[314],{"type":37,"value":155},{"type":32,"tag":94,"props":316,"children":317},{"style":101},[318],{"type":37,"value":115},{"type":32,"tag":94,"props":320,"children":321},{"style":107},[322],{"type":37,"value":323}," weeks_since_cohort,\n",{"type":32,"tag":94,"props":325,"children":327},{"class":96,"line":326},10,[328,333,338,343,348,352,356,360,364],{"type":32,"tag":94,"props":329,"children":330},{"style":137},[331],{"type":37,"value":332},"    COUNT",{"type":32,"tag":94,"props":334,"children":335},{"style":107},[336],{"type":37,"value":337},"(",{"type":32,"tag":94,"props":339,"children":340},{"style":101},[341],{"type":37,"value":342},"DISTINCT",{"type":32,"tag":94,"props":344,"children":345},{"style":137},[346],{"type":37,"value":347}," e",{"type":32,"tag":94,"props":349,"children":350},{"style":107},[351],{"type":37,"value":245},{"type":32,"tag":94,"props":353,"children":354},{"style":137},[355],{"type":37,"value":65},{"type":32,"tag":94,"props":357,"children":358},{"style":107},[359],{"type":37,"value":155},{"type":32,"tag":94,"props":361,"children":362},{"style":101},[363],{"type":37,"value":115},{"type":32,"tag":94,"props":365,"children":366},{"style":107},[367],{"type":37,"value":368}," active_users\n",{"type":32,"tag":94,"props":370,"children":372},{"class":96,"line":371},11,[373,377],{"type":32,"tag":94,"props":374,"children":375},{"style":101},[376],{"type":37,"value":173},{"type":32,"tag":94,"props":378,"children":379},{"style":107},[380],{"type":37,"value":381}," cohorts c\n",{"type":32,"tag":94,"props":383,"children":385},{"class":96,"line":384},12,[386,391,396,401,406,410,414,419,423,427],{"type":32,"tag":94,"props":387,"children":388},{"style":101},[389],{"type":37,"value":390},"  JOIN",{"type":32,"tag":94,"props":392,"children":393},{"style":107},[394],{"type":37,"value":395}," events e ",{"type":32,"tag":94,"props":397,"children":398},{"style":101},[399],{"type":37,"value":400},"ON",{"type":32,"tag":94,"props":402,"children":403},{"style":137},[404],{"type":37,"value":405}," c",{"type":32,"tag":94,"props":407,"children":408},{"style":107},[409],{"type":37,"value":245},{"type":32,"tag":94,"props":411,"children":412},{"style":137},[413],{"type":37,"value":65},{"type":32,"tag":94,"props":415,"children":416},{"style":101},[417],{"type":37,"value":418}," =",{"type":32,"tag":94,"props":420,"children":421},{"style":137},[422],{"type":37,"value":347},{"type":32,"tag":94,"props":424,"children":425},{"style":107},[426],{"type":37,"value":245},{"type":32,"tag":94,"props":428,"children":429},{"style":137},[430],{"type":37,"value":431},"user_id\n",{"type":32,"tag":94,"props":433,"children":435},{"class":96,"line":434},13,[436,440,445,449],{"type":32,"tag":94,"props":437,"children":438},{"style":101},[439],{"type":37,"value":187},{"type":32,"tag":94,"props":441,"children":442},{"style":137},[443],{"type":37,"value":444}," 1",{"type":32,"tag":94,"props":446,"children":447},{"style":107},[448],{"type":37,"value":67},{"type":32,"tag":94,"props":450,"children":451},{"style":137},[452],{"type":37,"value":453},"2\n",{"type":32,"tag":94,"props":455,"children":457},{"class":96,"line":456},14,[458],{"type":32,"tag":94,"props":459,"children":460},{"style":107},[461],{"type":37,"value":462},")\n",{"type":32,"tag":94,"props":464,"children":466},{"class":96,"line":465},15,[467,472,477,482,487,492,496,500,505],{"type":32,"tag":94,"props":468,"children":469},{"style":101},[470],{"type":37,"value":471},"SELECT",{"type":32,"tag":94,"props":473,"children":474},{"style":101},[475],{"type":37,"value":476}," *",{"type":32,"tag":94,"props":478,"children":479},{"style":101},[480],{"type":37,"value":481}," FROM",{"type":32,"tag":94,"props":483,"children":484},{"style":101},[485],{"type":37,"value":486}," retention",{"type":32,"tag":94,"props":488,"children":489},{"style":101},[490],{"type":37,"value":491}," ORDER BY",{"type":32,"tag":94,"props":493,"children":494},{"style":137},[495],{"type":37,"value":444},{"type":32,"tag":94,"props":497,"children":498},{"style":107},[499],{"type":37,"value":67},{"type":32,"tag":94,"props":501,"children":502},{"style":137},[503],{"type":37,"value":504},"2",{"type":32,"tag":94,"props":506,"children":507},{"style":107},[508],{"type":37,"value":509},";\n",{"type":32,"tag":33,"props":511,"children":512},{},[513,515,521],{"type":37,"value":514},"À chaque exécution, cette requête lit la table ",{"type":32,"tag":40,"props":516,"children":518},{"className":517},[],[519],{"type":37,"value":520},"events",{"type":37,"value":522}," entièrement. 500M lignes × 16 octets en moyenne = 8 GB scanné. À $6,25 par TB chez BigQuery, 1 000 requêtes = 50 $. Si votre dashboard rafraîchit tous les 5 minutes, 8 640 requêtes par mois = 432 $ pour le seul widget cohort. Ajoutez dix analystes supplémentaires, des bots Slack qui déclenchent des requêtes, et les coûts s'envolent.",{"type":32,"tag":33,"props":524,"children":525},{},[526],{"type":37,"value":527},"Le vrai problème n'est même pas le coût — c'est la latence. Un JOIN sur 500M lignes prend 15 à 30 secondes. L'utilisateur modifie un filtre dans le dashboard, puis attend 20 secondes pour les nouvelles données cohort. L'analyse de rétention ne peut pas être itérative avec ces délais.",{"type":32,"tag":529,"props":530,"children":532},"h3",{"id":531},"materialized-view-un-premier-pas-insuffisant",[533],{"type":37,"value":534},"Materialized View : un Premier Pas Insuffisant",{"type":32,"tag":33,"props":536,"children":537},{},[538],{"type":37,"value":539},"Une materialized view BigQuery pré-calcule la requête de cohort :",{"type":32,"tag":84,"props":541,"children":543},{"className":86,"code":542,"language":88,"meta":16,"style":16},"CREATE MATERIALIZED VIEW cohort_retention AS\nSELECT \n  cohort_week,\n  weeks_since_cohort,\n  active_users\nFROM retention; -- le résultat de la CTE ci-dessus\n",[544],{"type":32,"tag":40,"props":545,"children":546},{"__ignoreMap":16},[547,565,576,584,592,600],{"type":32,"tag":94,"props":548,"children":549},{"class":96,"line":97},[550,555,560],{"type":32,"tag":94,"props":551,"children":552},{"style":101},[553],{"type":37,"value":554},"CREATE",{"type":32,"tag":94,"props":556,"children":557},{"style":107},[558],{"type":37,"value":559}," MATERIALIZED VIEW cohort_retention ",{"type":32,"tag":94,"props":561,"children":562},{"style":101},[563],{"type":37,"value":564},"AS\n",{"type":32,"tag":94,"props":566,"children":567},{"class":96,"line":123},[568,572],{"type":32,"tag":94,"props":569,"children":570},{"style":101},[571],{"type":37,"value":471},{"type":32,"tag":94,"props":573,"children":574},{"style":107},[575],{"type":37,"value":231},{"type":32,"tag":94,"props":577,"children":578},{"class":96,"line":167},[579],{"type":32,"tag":94,"props":580,"children":581},{"style":107},[582],{"type":37,"value":583},"  cohort_week,\n",{"type":32,"tag":94,"props":585,"children":586},{"class":96,"line":181},[587],{"type":32,"tag":94,"props":588,"children":589},{"style":107},[590],{"type":37,"value":591},"  weeks_since_cohort,\n",{"type":32,"tag":94,"props":593,"children":594},{"class":96,"line":195},[595],{"type":32,"tag":94,"props":596,"children":597},{"style":107},[598],{"type":37,"value":599},"  active_users\n",{"type":32,"tag":94,"props":601,"children":602},{"class":96,"line":204},[603,608,612,617],{"type":32,"tag":94,"props":604,"children":605},{"style":101},[606],{"type":37,"value":607},"FROM",{"type":32,"tag":94,"props":609,"children":610},{"style":101},[611],{"type":37,"value":486},{"type":32,"tag":94,"props":613,"children":614},{"style":107},[615],{"type":37,"value":616},"; ",{"type":32,"tag":94,"props":618,"children":620},{"style":619},"--shiki-default:#6A737D",[621],{"type":37,"value":622},"-- le résultat de la CTE ci-dessus\n",{"type":32,"tag":33,"props":624,"children":625},{},[626,628,634,636,641],{"type":37,"value":627},"Maintenant, le dashboard lit ",{"type":32,"tag":40,"props":629,"children":631},{"className":630},[],[632],{"type":37,"value":633},"cohort_retention",{"type":37,"value":635}," au lieu de ",{"type":32,"tag":40,"props":637,"children":639},{"className":638},[],[640],{"type":37,"value":520},{"type":37,"value":642},". Le scan : 8 GB → 80 MB. La latence : 20 secondes → 800 ms. Mais deux limites émergent :",{"type":32,"tag":644,"props":645,"children":646},"ol",{},[647,659],{"type":32,"tag":648,"props":649,"children":650},"li",{},[651,657],{"type":32,"tag":652,"props":653,"children":654},"strong",{},[655],{"type":37,"value":656},"Coût du rafraîchissement :",{"type":37,"value":658}," À chaque refresh, la materialized view réexécute la requête de base. Soit 8 GB scannés. Si vous rafraîchissez la view une fois par heure, 24 × 8 GB = 192 GB\u002Fjour = 5,8 TB\u002Fmois scannés. Le coût n'a pas baissé, seulement la latence.",{"type":32,"tag":648,"props":660,"children":661},{},[662,667,669,675],{"type":32,"tag":652,"props":663,"children":664},{},[665],{"type":37,"value":666},"Manque de flexibilité :",{"type":37,"value":668}," La materialized view est statique. L'utilisateur ajoute un filtre « Rétention cohort Android », la view doit être recalculée. Vous ne pouvez pas ajouter ",{"type":32,"tag":40,"props":670,"children":672},{"className":671},[],[673],{"type":37,"value":674},"WHERE platform = 'Android'",{"type":37,"value":676}," à l'avance — chaque filtre demande une view différente.",{"type":32,"tag":33,"props":678,"children":679},{},[680],{"type":37,"value":681},"C'est pourquoi l'architecture cohort doit être tricouche : événements bruts → table d'affectation de cohort → table de rétention agrégée.",{"type":32,"tag":49,"props":683,"children":685},{"id":684},"isoler-la-table-daffectation-de-cohort",[686],{"type":37,"value":687},"Isoler la Table d'Affectation de Cohort",{"type":32,"tag":33,"props":689,"children":690},{},[691,693,698,700,705],{"type":37,"value":692},"Commencez par créer une table séparée qui assigne chaque utilisateur à son cohort. Cette table contient seulement ",{"type":32,"tag":40,"props":694,"children":696},{"className":695},[],[697],{"type":37,"value":65},{"type":37,"value":699}," et ",{"type":32,"tag":40,"props":701,"children":703},{"className":702},[],[704],{"type":37,"value":250},{"type":37,"value":706},", dérivée du log d'événements mais calculée une fois par jour :",{"type":32,"tag":84,"props":708,"children":710},{"className":86,"code":709,"language":88,"meta":16,"style":16},"CREATE OR REPLACE TABLE cohort_assignments\nPARTITION BY cohort_week\nCLUSTER BY user_id\nAS\nSELECT \n  user_id,\n  DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week,\n  MIN(event_time) AS first_seen_at\nFROM events\nWHERE event_time >= '2024-01-01'\nGROUP BY user_id;\n",[711],{"type":32,"tag":40,"props":712,"children":713},{"__ignoreMap":16},[714,733,750,767,774,785,793,826,848,859,883],{"type":32,"tag":94,"props":715,"children":716},{"class":96,"line":97},[717,722,727],{"type":32,"tag":94,"props":718,"children":719},{"style":101},[720],{"type":37,"value":721},"CREATE OR REPLACE",{"type":32,"tag":94,"props":723,"children":724},{"style":101},[725],{"type":37,"value":726}," TABLE",{"type":32,"tag":94,"props":728,"children":730},{"style":729},"--shiki-default:#B392F0",[731],{"type":37,"value":732}," cohort_assignments\n",{"type":32,"tag":94,"props":734,"children":735},{"class":96,"line":123},[736,741,746],{"type":32,"tag":94,"props":737,"children":738},{"style":101},[739],{"type":37,"value":740},"PARTITION",{"type":32,"tag":94,"props":742,"children":743},{"style":101},[744],{"type":37,"value":745}," BY",{"type":32,"tag":94,"props":747,"children":748},{"style":107},[749],{"type":37,"value":164},{"type":32,"tag":94,"props":751,"children":752},{"class":96,"line":167},[753,758,763],{"type":32,"tag":94,"props":754,"children":755},{"style":107},[756],{"type":37,"value":757},"CLUSTER ",{"type":32,"tag":94,"props":759,"children":760},{"style":101},[761],{"type":37,"value":762},"BY",{"type":32,"tag":94,"props":764,"children":765},{"style":107},[766],{"type":37,"value":192},{"type":32,"tag":94,"props":768,"children":769},{"class":96,"line":181},[770],{"type":32,"tag":94,"props":771,"children":772},{"style":101},[773],{"type":37,"value":564},{"type":32,"tag":94,"props":775,"children":776},{"class":96,"line":195},[777,781],{"type":32,"tag":94,"props":778,"children":779},{"style":101},[780],{"type":37,"value":471},{"type":32,"tag":94,"props":782,"children":783},{"style":107},[784],{"type":37,"value":231},{"type":32,"tag":94,"props":786,"children":787},{"class":96,"line":204},[788],{"type":32,"tag":94,"props":789,"children":790},{"style":107},[791],{"type":37,"value":792},"  user_id,\n",{"type":32,"tag":94,"props":794,"children":795},{"class":96,"line":221},[796,801,805,809,813,817,821],{"type":32,"tag":94,"props":797,"children":798},{"style":107},[799],{"type":37,"value":800},"  DATE_TRUNC(",{"type":32,"tag":94,"props":802,"children":803},{"style":137},[804],{"type":37,"value":140},{"type":32,"tag":94,"props":806,"children":807},{"style":107},[808],{"type":37,"value":145},{"type":32,"tag":94,"props":810,"children":811},{"style":101},[812],{"type":37,"value":150},{"type":32,"tag":94,"props":814,"children":815},{"style":107},[816],{"type":37,"value":155},{"type":32,"tag":94,"props":818,"children":819},{"style":101},[820],{"type":37,"value":115},{"type":32,"tag":94,"props":822,"children":823},{"style":107},[824],{"type":37,"value":825}," cohort_week,\n",{"type":32,"tag":94,"props":827,"children":828},{"class":96,"line":234},[829,834,839,843],{"type":32,"tag":94,"props":830,"children":831},{"style":137},[832],{"type":37,"value":833},"  MIN",{"type":32,"tag":94,"props":835,"children":836},{"style":107},[837],{"type":37,"value":838},"(event_time) ",{"type":32,"tag":94,"props":840,"children":841},{"style":101},[842],{"type":37,"value":115},{"type":32,"tag":94,"props":844,"children":845},{"style":107},[846],{"type":37,"value":847}," first_seen_at\n",{"type":32,"tag":94,"props":849,"children":850},{"class":96,"line":26},[851,855],{"type":32,"tag":94,"props":852,"children":853},{"style":101},[854],{"type":37,"value":607},{"type":32,"tag":94,"props":856,"children":857},{"style":107},[858],{"type":37,"value":178},{"type":32,"tag":94,"props":860,"children":861},{"class":96,"line":326},[862,867,872,877],{"type":32,"tag":94,"props":863,"children":864},{"style":101},[865],{"type":37,"value":866},"WHERE",{"type":32,"tag":94,"props":868,"children":869},{"style":107},[870],{"type":37,"value":871}," event_time ",{"type":32,"tag":94,"props":873,"children":874},{"style":101},[875],{"type":37,"value":876},">=",{"type":32,"tag":94,"props":878,"children":880},{"style":879},"--shiki-default:#9ECBFF",[881],{"type":37,"value":882}," '2024-01-01'\n",{"type":32,"tag":94,"props":884,"children":885},{"class":96,"line":371},[886,891],{"type":32,"tag":94,"props":887,"children":888},{"style":101},[889],{"type":37,"value":890},"GROUP BY",{"type":32,"tag":94,"props":892,"children":893},{"style":107},[894],{"type":37,"value":895}," user_id;\n",{"type":32,"tag":33,"props":897,"children":898},{},[899],{"type":37,"value":900},"Cette table :",{"type":32,"tag":902,"props":903,"children":904},"ul",{},[905,923,933],{"type":32,"tag":648,"props":906,"children":907},{},[908,913,915,921],{"type":32,"tag":652,"props":909,"children":910},{},[911],{"type":37,"value":912},"Partition par cohort_week :",{"type":37,"value":914}," BigQuery crée des blocs de fichiers séparés par semaine. Un filtre ",{"type":32,"tag":40,"props":916,"children":918},{"className":917},[],[919],{"type":37,"value":920},"WHERE cohort_week = '2026-01-05'",{"type":37,"value":922}," ne lit qu'une partition.",{"type":32,"tag":648,"props":924,"children":925},{},[926,931],{"type":32,"tag":652,"props":927,"children":928},{},[929],{"type":37,"value":930},"Cluster par user_id :",{"type":37,"value":932}," Au sein de chaque partition, le stockage est trié par user_id. Les JOIN s'accélèrent.",{"type":32,"tag":648,"props":934,"children":935},{},[936,941],{"type":32,"tag":652,"props":937,"children":938},{},[939],{"type":37,"value":940},"Taille :",{"type":37,"value":942}," 50M utilisateurs × 3 colonnes × 16 octets = ~2,4 GB. Comparé aux 500 GB du log d'événements, c'est 200× plus petit.",{"type":32,"tag":33,"props":944,"children":945},{},[946],{"type":37,"value":947},"Maintenant, la requête de rétention utilise cette table :",{"type":32,"tag":84,"props":949,"children":951},{"className":86,"code":950,"language":88,"meta":16,"style":16},"SELECT \n  c.cohort_week,\n  DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since,\n  COUNT(DISTINCT e.user_id) AS active_users\nFROM cohort_assignments c\nJOIN events e ON c.user_id = e.user_id\nWHERE c.cohort_week >= '2026-01-01'\nGROUP BY 1, 2;\n",[952],{"type":32,"tag":40,"props":953,"children":954},{"__ignoreMap":16},[955,966,986,1051,1091,1103,1147,1176],{"type":32,"tag":94,"props":956,"children":957},{"class":96,"line":97},[958,962],{"type":32,"tag":94,"props":959,"children":960},{"style":101},[961],{"type":37,"value":471},{"type":32,"tag":94,"props":963,"children":964},{"style":107},[965],{"type":37,"value":231},{"type":32,"tag":94,"props":967,"children":968},{"class":96,"line":123},[969,974,978,982],{"type":32,"tag":94,"props":970,"children":971},{"style":137},[972],{"type":37,"value":973},"  c",{"type":32,"tag":94,"props":975,"children":976},{"style":107},[977],{"type":37,"value":245},{"type":32,"tag":94,"props":979,"children":980},{"style":137},[981],{"type":37,"value":250},{"type":32,"tag":94,"props":983,"children":984},{"style":107},[985],{"type":37,"value":255},{"type":32,"tag":94,"props":987,"children":988},{"class":96,"line":167},[989,994,998,1002,1006,1010,1014,1018,1022,1026,1030,1034,1038,1042,1046],{"type":32,"tag":94,"props":990,"children":991},{"style":107},[992],{"type":37,"value":993},"  DATE_DIFF(DATE_TRUNC(",{"type":32,"tag":94,"props":995,"children":996},{"style":137},[997],{"type":37,"value":268},{"type":32,"tag":94,"props":999,"children":1000},{"style":107},[1001],{"type":37,"value":245},{"type":32,"tag":94,"props":1003,"children":1004},{"style":137},[1005],{"type":37,"value":73},{"type":32,"tag":94,"props":1007,"children":1008},{"style":107},[1009],{"type":37,"value":67},{"type":32,"tag":94,"props":1011,"children":1012},{"style":101},[1013],{"type":37,"value":150},{"type":32,"tag":94,"props":1015,"children":1016},{"style":107},[1017],{"type":37,"value":289},{"type":32,"tag":94,"props":1019,"children":1020},{"style":137},[1021],{"type":37,"value":294},{"type":32,"tag":94,"props":1023,"children":1024},{"style":107},[1025],{"type":37,"value":245},{"type":32,"tag":94,"props":1027,"children":1028},{"style":137},[1029],{"type":37,"value":250},{"type":32,"tag":94,"props":1031,"children":1032},{"style":107},[1033],{"type":37,"value":67},{"type":32,"tag":94,"props":1035,"children":1036},{"style":101},[1037],{"type":37,"value":150},{"type":32,"tag":94,"props":1039,"children":1040},{"style":107},[1041],{"type":37,"value":155},{"type":32,"tag":94,"props":1043,"children":1044},{"style":101},[1045],{"type":37,"value":115},{"type":32,"tag":94,"props":1047,"children":1048},{"style":107},[1049],{"type":37,"value":1050}," weeks_since,\n",{"type":32,"tag":94,"props":1052,"children":1053},{"class":96,"line":181},[1054,1059,1063,1067,1071,1075,1079,1083,1087],{"type":32,"tag":94,"props":1055,"children":1056},{"style":137},[1057],{"type":37,"value":1058},"  COUNT",{"type":32,"tag":94,"props":1060,"children":1061},{"style":107},[1062],{"type":37,"value":337},{"type":32,"tag":94,"props":1064,"children":1065},{"style":101},[1066],{"type":37,"value":342},{"type":32,"tag":94,"props":1068,"children":1069},{"style":137},[1070],{"type":37,"value":347},{"type":32,"tag":94,"props":1072,"children":1073},{"style":107},[1074],{"type":37,"value":245},{"type":32,"tag":94,"props":1076,"children":1077},{"style":137},[1078],{"type":37,"value":65},{"type":32,"tag":94,"props":1080,"children":1081},{"style":107},[1082],{"type":37,"value":155},{"type":32,"tag":94,"props":1084,"children":1085},{"style":101},[1086],{"type":37,"value":115},{"type":32,"tag":94,"props":1088,"children":1089},{"style":107},[1090],{"type":37,"value":368},{"type":32,"tag":94,"props":1092,"children":1093},{"class":96,"line":195},[1094,1098],{"type":32,"tag":94,"props":1095,"children":1096},{"style":101},[1097],{"type":37,"value":607},{"type":32,"tag":94,"props":1099,"children":1100},{"style":107},[1101],{"type":37,"value":1102}," cohort_assignments c\n",{"type":32,"tag":94,"props":1104,"children":1105},{"class":96,"line":204},[1106,1111,1115,1119,1123,1127,1131,1135,1139,1143],{"type":32,"tag":94,"props":1107,"children":1108},{"style":101},[1109],{"type":37,"value":1110},"JOIN",{"type":32,"tag":94,"props":1112,"children":1113},{"style":107},[1114],{"type":37,"value":395},{"type":32,"tag":94,"props":1116,"children":1117},{"style":101},[1118],{"type":37,"value":400},{"type":32,"tag":94,"props":1120,"children":1121},{"style":137},[1122],{"type":37,"value":405},{"type":32,"tag":94,"props":1124,"children":1125},{"style":107},[1126],{"type":37,"value":245},{"type":32,"tag":94,"props":1128,"children":1129},{"style":137},[1130],{"type":37,"value":65},{"type":32,"tag":94,"props":1132,"children":1133},{"style":101},[1134],{"type":37,"value":418},{"type":32,"tag":94,"props":1136,"children":1137},{"style":137},[1138],{"type":37,"value":347},{"type":32,"tag":94,"props":1140,"children":1141},{"style":107},[1142],{"type":37,"value":245},{"type":32,"tag":94,"props":1144,"children":1145},{"style":137},[1146],{"type":37,"value":431},{"type":32,"tag":94,"props":1148,"children":1149},{"class":96,"line":221},[1150,1154,1158,1162,1166,1171],{"type":32,"tag":94,"props":1151,"children":1152},{"style":101},[1153],{"type":37,"value":866},{"type":32,"tag":94,"props":1155,"children":1156},{"style":137},[1157],{"type":37,"value":405},{"type":32,"tag":94,"props":1159,"children":1160},{"style":107},[1161],{"type":37,"value":245},{"type":32,"tag":94,"props":1163,"children":1164},{"style":137},[1165],{"type":37,"value":250},{"type":32,"tag":94,"props":1167,"children":1168},{"style":101},[1169],{"type":37,"value":1170}," >=",{"type":32,"tag":94,"props":1172,"children":1173},{"style":879},[1174],{"type":37,"value":1175}," '2026-01-01'\n",{"type":32,"tag":94,"props":1177,"children":1178},{"class":96,"line":234},[1179,1183,1187,1191,1195],{"type":32,"tag":94,"props":1180,"children":1181},{"style":101},[1182],{"type":37,"value":890},{"type":32,"tag":94,"props":1184,"children":1185},{"style":137},[1186],{"type":37,"value":444},{"type":32,"tag":94,"props":1188,"children":1189},{"style":107},[1190],{"type":37,"value":67},{"type":32,"tag":94,"props":1192,"children":1193},{"style":137},[1194],{"type":37,"value":504},{"type":32,"tag":94,"props":1196,"children":1197},{"style":107},[1198],{"type":37,"value":509},{"type":32,"tag":33,"props":1200,"children":1201},{},[1202,1204,1210,1212,1217],{"type":37,"value":1203},"Avec le partition pruning, la lecture de 4 semaines de ",{"type":32,"tag":40,"props":1205,"children":1207},{"className":1206},[],[1208],{"type":37,"value":1209},"cohort_assignments",{"type":37,"value":1211}," = 200 MB scannés. Le JOIN traite toujours ",{"type":32,"tag":40,"props":1213,"children":1215},{"className":1214},[],[1216],{"type":37,"value":520},{"type":37,"value":1218},", mais commence à partir d'utilisateurs filtrés par cohort — pas de surcharge inutile.",{"type":32,"tag":529,"props":1220,"children":1222},{"id":1221},"mise-à-jour-incrémentale",[1223],{"type":37,"value":1224},"Mise à Jour Incrémentale",{"type":32,"tag":33,"props":1226,"children":1227},{},[1228,1233],{"type":32,"tag":40,"props":1229,"children":1231},{"className":1230},[],[1232],{"type":37,"value":1209},{"type":37,"value":1234}," se renouvelle quotidiennement, mais pas de zéro. Utilisez un modèle incrémental dbt :",{"type":32,"tag":84,"props":1236,"children":1238},{"className":86,"code":1237,"language":88,"meta":16,"style":16},"{{\n  config(\n    materialized='incremental',\n    partition_by={'field': 'cohort_week', 'data_type': 'date'},\n    cluster_by=['user_id']\n  )\n}}\n\nSELECT \n  user_id,\n  DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week,\n  MIN(event_time) AS first_seen_at\nFROM {{ ref('events') }}\n{% if is_incremental() %}\n  WHERE event_time > (SELECT MAX(first_seen_at) FROM {{ this }})\n{% endif %}\nGROUP BY user_id\n",[1239],{"type":32,"tag":40,"props":1240,"children":1241},{"__ignoreMap":16},[1242,1250,1258,1280,1335,1352,1360,1368,1377,1388,1395,1426,1445,1467,1485,1530,1539],{"type":32,"tag":94,"props":1243,"children":1244},{"class":96,"line":97},[1245],{"type":32,"tag":94,"props":1246,"children":1247},{"style":107},[1248],{"type":37,"value":1249},"{{\n",{"type":32,"tag":94,"props":1251,"children":1252},{"class":96,"line":123},[1253],{"type":32,"tag":94,"props":1254,"children":1255},{"style":107},[1256],{"type":37,"value":1257},"  config(\n",{"type":32,"tag":94,"props":1259,"children":1260},{"class":96,"line":167},[1261,1266,1271,1276],{"type":32,"tag":94,"props":1262,"children":1263},{"style":107},[1264],{"type":37,"value":1265},"    materialized",{"type":32,"tag":94,"props":1267,"children":1268},{"style":101},[1269],{"type":37,"value":1270},"=",{"type":32,"tag":94,"props":1272,"children":1273},{"style":879},[1274],{"type":37,"value":1275},"'incremental'",{"type":32,"tag":94,"props":1277,"children":1278},{"style":107},[1279],{"type":37,"value":255},{"type":32,"tag":94,"props":1281,"children":1282},{"class":96,"line":181},[1283,1288,1292,1297,1302,1307,1312,1316,1321,1325,1330],{"type":32,"tag":94,"props":1284,"children":1285},{"style":107},[1286],{"type":37,"value":1287},"    partition_by",{"type":32,"tag":94,"props":1289,"children":1290},{"style":101},[1291],{"type":37,"value":1270},{"type":32,"tag":94,"props":1293,"children":1294},{"style":107},[1295],{"type":37,"value":1296},"{",{"type":32,"tag":94,"props":1298,"children":1299},{"style":879},[1300],{"type":37,"value":1301},"'field'",{"type":32,"tag":94,"props":1303,"children":1304},{"style":107},[1305],{"type":37,"value":1306},": ",{"type":32,"tag":94,"props":1308,"children":1309},{"style":879},[1310],{"type":37,"value":1311},"'cohort_week'",{"type":32,"tag":94,"props":1313,"children":1314},{"style":107},[1315],{"type":37,"value":67},{"type":32,"tag":94,"props":1317,"children":1318},{"style":879},[1319],{"type":37,"value":1320},"'data_type'",{"type":32,"tag":94,"props":1322,"children":1323},{"style":107},[1324],{"type":37,"value":1306},{"type":32,"tag":94,"props":1326,"children":1327},{"style":879},[1328],{"type":37,"value":1329},"'date'",{"type":32,"tag":94,"props":1331,"children":1332},{"style":107},[1333],{"type":37,"value":1334},"},\n",{"type":32,"tag":94,"props":1336,"children":1337},{"class":96,"line":195},[1338,1343,1347],{"type":32,"tag":94,"props":1339,"children":1340},{"style":107},[1341],{"type":37,"value":1342},"    cluster_by",{"type":32,"tag":94,"props":1344,"children":1345},{"style":101},[1346],{"type":37,"value":1270},{"type":32,"tag":94,"props":1348,"children":1349},{"style":107},[1350],{"type":37,"value":1351},"['user_id']\n",{"type":32,"tag":94,"props":1353,"children":1354},{"class":96,"line":204},[1355],{"type":32,"tag":94,"props":1356,"children":1357},{"style":107},[1358],{"type":37,"value":1359},"  )\n",{"type":32,"tag":94,"props":1361,"children":1362},{"class":96,"line":221},[1363],{"type":32,"tag":94,"props":1364,"children":1365},{"style":107},[1366],{"type":37,"value":1367},"}}\n",{"type":32,"tag":94,"props":1369,"children":1370},{"class":96,"line":234},[1371],{"type":32,"tag":94,"props":1372,"children":1374},{"emptyLinePlaceholder":1373},true,[1375],{"type":37,"value":1376},"\n",{"type":32,"tag":94,"props":1378,"children":1379},{"class":96,"line":26},[1380,1384],{"type":32,"tag":94,"props":1381,"children":1382},{"style":101},[1383],{"type":37,"value":471},{"type":32,"tag":94,"props":1385,"children":1386},{"style":107},[1387],{"type":37,"value":231},{"type":32,"tag":94,"props":1389,"children":1390},{"class":96,"line":326},[1391],{"type":32,"tag":94,"props":1392,"children":1393},{"style":107},[1394],{"type":37,"value":792},{"type":32,"tag":94,"props":1396,"children":1397},{"class":96,"line":371},[1398,1402,1406,1410,1414,1418,1422],{"type":32,"tag":94,"props":1399,"children":1400},{"style":107},[1401],{"type":37,"value":800},{"type":32,"tag":94,"props":1403,"children":1404},{"style":137},[1405],{"type":37,"value":140},{"type":32,"tag":94,"props":1407,"children":1408},{"style":107},[1409],{"type":37,"value":145},{"type":32,"tag":94,"props":1411,"children":1412},{"style":101},[1413],{"type":37,"value":150},{"type":32,"tag":94,"props":1415,"children":1416},{"style":107},[1417],{"type":37,"value":155},{"type":32,"tag":94,"props":1419,"children":1420},{"style":101},[1421],{"type":37,"value":115},{"type":32,"tag":94,"props":1423,"children":1424},{"style":107},[1425],{"type":37,"value":825},{"type":32,"tag":94,"props":1427,"children":1428},{"class":96,"line":384},[1429,1433,1437,1441],{"type":32,"tag":94,"props":1430,"children":1431},{"style":137},[1432],{"type":37,"value":833},{"type":32,"tag":94,"props":1434,"children":1435},{"style":107},[1436],{"type":37,"value":838},{"type":32,"tag":94,"props":1438,"children":1439},{"style":101},[1440],{"type":37,"value":115},{"type":32,"tag":94,"props":1442,"children":1443},{"style":107},[1444],{"type":37,"value":847},{"type":32,"tag":94,"props":1446,"children":1447},{"class":96,"line":434},[1448,1452,1457,1462],{"type":32,"tag":94,"props":1449,"children":1450},{"style":101},[1451],{"type":37,"value":607},{"type":32,"tag":94,"props":1453,"children":1454},{"style":107},[1455],{"type":37,"value":1456}," {{ ref(",{"type":32,"tag":94,"props":1458,"children":1459},{"style":879},[1460],{"type":37,"value":1461},"'events'",{"type":32,"tag":94,"props":1463,"children":1464},{"style":107},[1465],{"type":37,"value":1466},") }}\n",{"type":32,"tag":94,"props":1468,"children":1469},{"class":96,"line":456},[1470,1475,1480],{"type":32,"tag":94,"props":1471,"children":1472},{"style":107},[1473],{"type":37,"value":1474},"{% ",{"type":32,"tag":94,"props":1476,"children":1477},{"style":101},[1478],{"type":37,"value":1479},"if",{"type":32,"tag":94,"props":1481,"children":1482},{"style":107},[1483],{"type":37,"value":1484}," is_incremental() %}\n",{"type":32,"tag":94,"props":1486,"children":1487},{"class":96,"line":465},[1488,1493,1497,1502,1507,1511,1516,1521,1525],{"type":32,"tag":94,"props":1489,"children":1490},{"style":101},[1491],{"type":37,"value":1492},"  WHERE",{"type":32,"tag":94,"props":1494,"children":1495},{"style":107},[1496],{"type":37,"value":871},{"type":32,"tag":94,"props":1498,"children":1499},{"style":101},[1500],{"type":37,"value":1501},">",{"type":32,"tag":94,"props":1503,"children":1504},{"style":107},[1505],{"type":37,"value":1506}," (",{"type":32,"tag":94,"props":1508,"children":1509},{"style":101},[1510],{"type":37,"value":471},{"type":32,"tag":94,"props":1512,"children":1513},{"style":137},[1514],{"type":37,"value":1515}," MAX",{"type":32,"tag":94,"props":1517,"children":1518},{"style":107},[1519],{"type":37,"value":1520},"(first_seen_at) ",{"type":32,"tag":94,"props":1522,"children":1523},{"style":101},[1524],{"type":37,"value":607},{"type":32,"tag":94,"props":1526,"children":1527},{"style":107},[1528],{"type":37,"value":1529}," {{ this }})\n",{"type":32,"tag":94,"props":1531,"children":1533},{"class":96,"line":1532},16,[1534],{"type":32,"tag":94,"props":1535,"children":1536},{"style":107},[1537],{"type":37,"value":1538},"{% endif %}\n",{"type":32,"tag":94,"props":1540,"children":1542},{"class":96,"line":1541},17,[1543,1547],{"type":32,"tag":94,"props":1544,"children":1545},{"style":101},[1546],{"type":37,"value":890},{"type":32,"tag":94,"props":1548,"children":1549},{"style":107},[1550],{"type":37,"value":192},{"type":32,"tag":33,"props":1552,"children":1553},{},[1554],{"type":37,"value":1555},"Ce modèle traite tous les historiques à la première exécution, puis ajoute seulement les nouveaux utilisateurs. Scan : 500 GB → 2 GB par jour.",{"type":32,"tag":49,"props":1557,"children":1559},{"id":1558},"table-de-rétention-agrégée-pré-calcul-au-niveau-hebdomadaire",[1560],{"type":37,"value":1561},"Table de Rétention Agrégée : Pré-Calcul au Niveau Hebdomadaire",{"type":32,"tag":33,"props":1563,"children":1564},{},[1565,1570,1572,1577],{"type":32,"tag":40,"props":1566,"children":1568},{"className":1567},[],[1569],{"type":37,"value":1209},{"type":37,"value":1571}," accélère les requêtes de rétention, mais le dashboard JOIN'e toujours ",{"type":32,"tag":40,"props":1573,"children":1575},{"className":1574},[],[1576],{"type":37,"value":520},{"type":37,"value":1578}," à la demande. Un pas supplémentaire : pré-calculez les métriques de rétention au niveau hebdomadaire, stockées dans une table séparée.",{"type":32,"tag":84,"props":1580,"children":1582},{"className":86,"code":1581,"language":88,"meta":16,"style":16},"CREATE TABLE cohort_retention_weekly\nPARTITION BY cohort_week\nCLUSTER BY weeks_since_cohort\nAS\nSELECT \n  c.cohort_week,\n  DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since_cohort,\n  COUNT(DISTINCT e.user_id) AS active_users,\n  COUNT(*) AS total_events,\n  APPROX_QUANTILES(session_duration, 100)[OFFSET(50)] AS median_session_duration\nFROM cohort_assignments c\nJOIN events e ON c.user_id = e.user_id\nGROUP BY 1, 2;\n",[1583],{"type":32,"tag":40,"props":1584,"children":1585},{"__ignoreMap":16},[1586,1602,1617,1633,1640,1651,1670,1733,1773,1802,1829,1840,1883],{"type":32,"tag":94,"props":1587,"children":1588},{"class":96,"line":97},[1589,1593,1597],{"type":32,"tag":94,"props":1590,"children":1591},{"style":101},[1592],{"type":37,"value":554},{"type":32,"tag":94,"props":1594,"children":1595},{"style":101},[1596],{"type":37,"value":726},{"type":32,"tag":94,"props":1598,"children":1599},{"style":729},[1600],{"type":37,"value":1601}," cohort_retention_weekly\n",{"type":32,"tag":94,"props":1603,"children":1604},{"class":96,"line":123},[1605,1609,1613],{"type":32,"tag":94,"props":1606,"children":1607},{"style":101},[1608],{"type":37,"value":740},{"type":32,"tag":94,"props":1610,"children":1611},{"style":101},[1612],{"type":37,"value":745},{"type":32,"tag":94,"props":1614,"children":1615},{"style":107},[1616],{"type":37,"value":164},{"type":32,"tag":94,"props":1618,"children":1619},{"class":96,"line":167},[1620,1624,1628],{"type":32,"tag":94,"props":1621,"children":1622},{"style":107},[1623],{"type":37,"value":757},{"type":32,"tag":94,"props":1625,"children":1626},{"style":101},[1627],{"type":37,"value":762},{"type":32,"tag":94,"props":1629,"children":1630},{"style":107},[1631],{"type":37,"value":1632}," weeks_since_cohort\n",{"type":32,"tag":94,"props":1634,"children":1635},{"class":96,"line":181},[1636],{"type":32,"tag":94,"props":1637,"children":1638},{"style":101},[1639],{"type":37,"value":564},{"type":32,"tag":94,"props":1641,"children":1642},{"class":96,"line":195},[1643,1647],{"type":32,"tag":94,"props":1644,"children":1645},{"style":101},[1646],{"type":37,"value":471},{"type":32,"tag":94,"props":1648,"children":1649},{"style":107},[1650],{"type":37,"value":231},{"type":32,"tag":94,"props":1652,"children":1653},{"class":96,"line":204},[1654,1658,1662,1666],{"type":32,"tag":94,"props":1655,"children":1656},{"style":137},[1657],{"type":37,"value":973},{"type":32,"tag":94,"props":1659,"children":1660},{"style":107},[1661],{"type":37,"value":245},{"type":32,"tag":94,"props":1663,"children":1664},{"style":137},[1665],{"type":37,"value":250},{"type":32,"tag":94,"props":1667,"children":1668},{"style":107},[1669],{"type":37,"value":255},{"type":32,"tag":94,"props":1671,"children":1672},{"class":96,"line":221},[1673,1677,1681,1685,1689,1693,1697,1701,1705,1709,1713,1717,1721,1725,1729],{"type":32,"tag":94,"props":1674,"children":1675},{"style":107},[1676],{"type":37,"value":993},{"type":32,"tag":94,"props":1678,"children":1679},{"style":137},[1680],{"type":37,"value":268},{"type":32,"tag":94,"props":1682,"children":1683},{"style":107},[1684],{"type":37,"value":245},{"type":32,"tag":94,"props":1686,"children":1687},{"style":137},[1688],{"type":37,"value":73},{"type":32,"tag":94,"props":1690,"children":1691},{"style":107},[1692],{"type":37,"value":67},{"type":32,"tag":94,"props":1694,"children":1695},{"style":101},[1696],{"type":37,"value":150},{"type":32,"tag":94,"props":1698,"children":1699},{"style":107},[1700],{"type":37,"value":289},{"type":32,"tag":94,"props":1702,"children":1703},{"style":137},[1704],{"type":37,"value":294},{"type":32,"tag":94,"props":1706,"children":1707},{"style":107},[1708],{"type":37,"value":245},{"type":32,"tag":94,"props":1710,"children":1711},{"style":137},[1712],{"type":37,"value":250},{"type":32,"tag":94,"props":1714,"children":1715},{"style":107},[1716],{"type":37,"value":67},{"type":32,"tag":94,"props":1718,"children":1719},{"style":101},[1720],{"type":37,"value":150},{"type":32,"tag":94,"props":1722,"children":1723},{"style":107},[1724],{"type":37,"value":155},{"type":32,"tag":94,"props":1726,"children":1727},{"style":101},[1728],{"type":37,"value":115},{"type":32,"tag":94,"props":1730,"children":1731},{"style":107},[1732],{"type":37,"value":323},{"type":32,"tag":94,"props":1734,"children":1735},{"class":96,"line":234},[1736,1740,1744,1748,1752,1756,1760,1764,1768],{"type":32,"tag":94,"props":1737,"children":1738},{"style":137},[1739],{"type":37,"value":1058},{"type":32,"tag":94,"props":1741,"children":1742},{"style":107},[1743],{"type":37,"value":337},{"type":32,"tag":94,"props":1745,"children":1746},{"style":101},[1747],{"type":37,"value":342},{"type":32,"tag":94,"props":1749,"children":1750},{"style":137},[1751],{"type":37,"value":347},{"type":32,"tag":94,"props":1753,"children":1754},{"style":107},[1755],{"type":37,"value":245},{"type":32,"tag":94,"props":1757,"children":1758},{"style":137},[1759],{"type":37,"value":65},{"type":32,"tag":94,"props":1761,"children":1762},{"style":107},[1763],{"type":37,"value":155},{"type":32,"tag":94,"props":1765,"children":1766},{"style":101},[1767],{"type":37,"value":115},{"type":32,"tag":94,"props":1769,"children":1770},{"style":107},[1771],{"type":37,"value":1772}," active_users,\n",{"type":32,"tag":94,"props":1774,"children":1775},{"class":96,"line":26},[1776,1780,1784,1789,1793,1797],{"type":32,"tag":94,"props":1777,"children":1778},{"style":137},[1779],{"type":37,"value":1058},{"type":32,"tag":94,"props":1781,"children":1782},{"style":107},[1783],{"type":37,"value":337},{"type":32,"tag":94,"props":1785,"children":1786},{"style":101},[1787],{"type":37,"value":1788},"*",{"type":32,"tag":94,"props":1790,"children":1791},{"style":107},[1792],{"type":37,"value":155},{"type":32,"tag":94,"props":1794,"children":1795},{"style":101},[1796],{"type":37,"value":115},{"type":32,"tag":94,"props":1798,"children":1799},{"style":107},[1800],{"type":37,"value":1801}," total_events,\n",{"type":32,"tag":94,"props":1803,"children":1804},{"class":96,"line":326},[1805,1810,1815,1820,1824],{"type":32,"tag":94,"props":1806,"children":1807},{"style":107},[1808],{"type":37,"value":1809},"  APPROX_QUANTILES(session_duration, ",{"type":32,"tag":94,"props":1811,"children":1812},{"style":137},[1813],{"type":37,"value":1814},"100",{"type":32,"tag":94,"props":1816,"children":1817},{"style":107},[1818],{"type":37,"value":1819},")[OFFSET(50)] ",{"type":32,"tag":94,"props":1821,"children":1822},{"style":101},[1823],{"type":37,"value":115},{"type":32,"tag":94,"props":1825,"children":1826},{"style":107},[1827],{"type":37,"value":1828}," median_session_duration\n",{"type":32,"tag":94,"props":1830,"children":1831},{"class":96,"line":371},[1832,1836],{"type":32,"tag":94,"props":1833,"children":1834},{"style":101},[1835],{"type":37,"value":607},{"type":32,"tag":94,"props":1837,"children":1838},{"style":107},[1839],{"type":37,"value":1102},{"type":32,"tag":94,"props":1841,"children":1842},{"class":96,"line":384},[1843,1847,1851,1855,1859,1863,1867,1871,1875,1879],{"type":32,"tag":94,"props":1844,"children":1845},{"style":101},[1846],{"type":37,"value":1110},{"type":32,"tag":94,"props":1848,"children":1849},{"style":107},[1850],{"type":37,"value":395},{"type":32,"tag":94,"props":1852,"children":1853},{"style":101},[1854],{"type":37,"value":400},{"type":32,"tag":94,"props":1856,"children":1857},{"style":137},[1858],{"type":37,"value":405},{"type":32,"tag":94,"props":1860,"children":1861},{"style":107},[1862],{"type":37,"value":245},{"type":32,"tag":94,"props":1864,"children":1865},{"style":137},[1866],{"type":37,"value":65},{"type":32,"tag":94,"props":1868,"children":1869},{"style":101},[1870],{"type":37,"value":418},{"type":32,"tag":94,"props":1872,"children":1873},{"style":137},[1874],{"type":37,"value":347},{"type":32,"tag":94,"props":1876,"children":1877},{"style":107},[1878],{"type":37,"value":245},{"type":32,"tag":94,"props":1880,"children":1881},{"style":137},[1882],{"type":37,"value":431},{"type":32,"tag":94,"props":1884,"children":1885},{"class":96,"line":434},[1886,1890,1894,1898,1902],{"type":32,"tag":94,"props":1887,"children":1888},{"style":101},[1889],{"type":37,"value":890},{"type":32,"tag":94,"props":1891,"children":1892},{"style":137},[1893],{"type":37,"value":444},{"type":32,"tag":94,"props":1895,"children":1896},{"style":107},[1897],{"type":37,"value":67},{"type":32,"tag":94,"props":1899,"children":1900},{"style":137},[1901],{"type":37,"value":504},{"type":32,"tag":94,"props":1903,"children":1904},{"style":107},[1905],{"type":37,"value":509},{"type":32,"tag":33,"props":1907,"children":1908},{},[1909],{"type":37,"value":900},{"type":32,"tag":902,"props":1911,"children":1912},{},[1913,1922,1947],{"type":32,"tag":648,"props":1914,"children":1915},{},[1916,1920],{"type":32,"tag":652,"props":1917,"children":1918},{},[1919],{"type":37,"value":940},{"type":37,"value":1921}," 52 semaines × 52 weeks_since × 3 métriques = ~8 100 lignes (pour 1 an de données). À l'échelle de quelques KB.",{"type":32,"tag":648,"props":1923,"children":1924},{},[1925,1930,1932,1938,1940,1945],{"type":32,"tag":652,"props":1926,"children":1927},{},[1928],{"type":37,"value":1929},"Scan :",{"type":37,"value":1931}," Le dashboard lit ",{"type":32,"tag":40,"props":1933,"children":1935},{"className":1934},[],[1936],{"type":37,"value":1937},"cohort_retention_weekly",{"type":37,"value":1939},", zéro lecture de ",{"type":32,"tag":40,"props":1941,"children":1943},{"className":1942},[],[1944],{"type":37,"value":520},{"type":37,"value":1946},". Scan \u003C 1 MB.",{"type":32,"tag":648,"props":1948,"children":1949},{},[1950,1955],{"type":32,"tag":652,"props":1951,"children":1952},{},[1953],{"type":37,"value":1954},"Latence :",{"type":37,"value":1956}," BigQuery lit 1 MB en ~80 ms. Le dashboard atteint le sub-seconde.",{"type":32,"tag":33,"props":1958,"children":1959},{},[1960,1962,1968],{"type":37,"value":1961},"Tradeoff : cette table doit être renouvelée quotidiennement. Si les données doivent être à jour, rafraîchissez chaque heure (schedule dbt ",{"type":32,"tag":40,"props":1963,"children":1965},{"className":1964},[],[1966],{"type":37,"value":1967},"0 * * * *",{"type":37,"value":1969},"). Le coût du refresh : JOIN cohort_assignments avec events, ~10 GB scannés. 24× par jour = 240 GB, ~7,2 TB\u002Fmois. Comparaison : si le dashboard exécutait 1 000 requêtes cohort sans pré-agrégation, 8 TB scannés. La table agrégée réduit le scan de %10, mais la latence passe de 20 secondes à 80 ms.",{"type":32,"tag":529,"props":1971,"children":1973},{"id":1972},"stratégie-de-partitioning-cohort-week-vs-event-week",[1974],{"type":37,"value":1975},"Stratégie de Partitioning : Cohort Week vs Event Week",{"type":32,"tag":33,"props":1977,"children":1978},{},[1979,1981,1986,1988,1994],{"type":37,"value":1980},"Faut-il partitionner la table de rétention cohort par ",{"type":32,"tag":40,"props":1982,"children":1984},{"className":1983},[],[1985],{"type":37,"value":250},{"type":37,"value":1987}," ou ",{"type":32,"tag":40,"props":1989,"children":1991},{"className":1990},[],[1992],{"type":37,"value":1993},"event_week",{"type":37,"value":1995}," ? Deux approches :",{"type":32,"tag":33,"props":1997,"children":1998},{},[1999],{"type":32,"tag":652,"props":2000,"children":2001},{},[2002],{"type":37,"value":912},{"type":32,"tag":902,"props":2004,"children":2005},{},[2006,2011,2024],{"type":32,"tag":648,"props":2007,"children":2008},{},[2009],{"type":37,"value":2010},"Cas d'usage : « Quelle est la courbe de rétention de la cohort 2026-W03 ? »",{"type":32,"tag":648,"props":2012,"children":2013},{},[2014,2016,2022],{"type":37,"value":2015},"Pruning : ",{"type":32,"tag":40,"props":2017,"children":2019},{"className":2018},[],[2020],{"type":37,"value":2021},"WHERE cohort_week = '2026-01-13'",{"type":37,"value":2023}," → 1 partition lue",{"type":32,"tag":648,"props":2025,"children":2026},{},[2027],{"type":37,"value":2028},"Défi : Si le dashboard demande « rétention totale des 4 dernières semaines », 4 partitions sont lues. Mais comme 80 % des requêtes de rétention se font par cohort, c'est optimal.",{"type":32,"tag":33,"props":2030,"children":2031},{},[2032],{"type":32,"tag":652,"props":2033,"children":2034},{},[2035],{"type":37,"value":2036},"Partition par event_week :",{"type":32,"tag":902,"props":2038,"children":2039},{},[2040,2045,2057],{"type":32,"tag":648,"props":2041,"children":2042},{},[2043],{"type":37,"value":2044},"Cas d'usage : « Quelles cohorts étaient actives cette semaine ? »",{"type":32,"tag":648,"props":2046,"children":2047},{},[2048,2049,2055],{"type":37,"value":2015},{"type":32,"tag":40,"props":2050,"children":2052},{"className":2051},[],[2053],{"type":37,"value":2054},"WHERE event_week = '2026-07-21'",{"type":37,"value":2056}," → 1 partition",{"type":32,"tag":648,"props":2058,"children":2059},{},[2060],{"type":37,"value":2061},"Défi : Ajouter un filtre cohort désactive le pruning ; toutes les partitions sont lues.",{"type":32,"tag":33,"props":2063,"children":2064},{},[2065,2067,2076],{"type":37,"value":2066},"Roibase partitionne par cohort_week dans les ",{"type":32,"tag":2068,"props":2069,"children":2073},"a",{"href":2070,"rel":2071},"https:\u002F\u002Fwww.roibase.com.tr\u002Ffr\u002Fverianalizi",[2072],"nofollow",[2074],{"type":37,"value":2075},"architectures d'analyse de données",{"type":37,"value":2077},", car 80 % des requêtes suivent le motif « Cohort X, semaine N ».",{"type":32,"tag":49,"props":2079,"children":2081},{"id":2080},"optimisation-des-coûts-de-requête-clustering-et-bi-engine",[2082],{"type":37,"value":2083},"Optimisation des Coûts de Requête : Clustering et BI Engine",{"type":32,"tag":33,"props":2085,"children":2086},{},[2087],{"type":37,"value":2088},"Le partitioning élimine les blocs de fichiers (pruning de haut en bas), le clustering ordonne les lignes (pruning de gauche à droite). Ensemble, ils minimisent les scans.",{"type":32,"tag":84,"props":2090,"children":2092},{"className":86,"code":2091,"language":88,"meta":16,"style":16},"CREATE TABLE cohort_retention_weekly\nPARTITION BY cohort_week\nCLUSTER BY weeks_since_cohort, platform, country;\n",[2093],{"type":32,"tag":40,"props":2094,"children":2095},{"__ignoreMap":16},[2096,2111,2126],{"type":32,"tag":94,"props":2097,"children":2098},{"class":96,"line":97},[2099,2103,2107],{"type":32,"tag":94,"props":2100,"children":2101},{"style":101},[2102],{"type":37,"value":554},{"type":32,"tag":94,"props":2104,"children":2105},{"style":101},[2106],{"type":37,"value":726},{"type":32,"tag":94,"props":2108,"children":2109},{"style":729},[2110],{"type":37,"value":1601},{"type":32,"tag":94,"props":2112,"children":2113},{"class":96,"line":123},[2114,2118,2122],{"type":32,"tag":94,"props":2115,"children":2116},{"style":101},[2117],{"type":37,"value":740},{"type":32,"tag":94,"props":2119,"children":2120},{"style":101},[2121],{"type":37,"value":745},{"type":32,"tag":94,"props":2123,"children":2124},{"style":107},[2125],{"type":37,"value":164},{"type":32,"tag":94,"props":2127,"children":2128},{"class":96,"line":167},[2129,2133,2137],{"type":32,"tag":94,"props":2130,"children":2131},{"style":107},[2132],{"type":37,"value":757},{"type":32,"tag":94,"props":2134,"children":2135},{"style":101},[2136],{"type":37,"value":762},{"type":32,"tag":94,"props":2138,"children":2139},{"style":107},[2140],{"type":37,"value":2141}," weeks_since_cohort, platform, country;\n",{"type":32,"tag":33,"props":2143,"children":2144},{},[2145,2147,2153],{"type":37,"value":2146},"Une requête ",{"type":32,"tag":40,"props":2148,"children":2150},{"className":2149},[],[2151],{"type":37,"value":2152},"WHERE weeks_since_cohort = 4 AND platform = 'iOS'",{"type":37,"value":2154}," :",{"type":32,"tag":644,"props":2156,"children":2157},{},[2158,2163],{"type":32,"tag":648,"props":2159,"children":2160},{},[2161],{"type":37,"value":2162},"Partition pruning → lit seulement les partitions cohort_week pertinentes",{"type":32,"tag":648,"props":2164,"children":2165},{},[2166,2168,2174,2176],{"type":37,"value":2167},"Clustering → au sein de la partition, localise d'abord ",{"type":32,"tag":40,"props":2169,"children":2171},{"className":2170},[],[2172],{"type":37,"value":2173},"weeks_since_cohort = 4",{"type":37,"value":2175},", puis ",{"type":32,"tag":40,"props":2177,"children":2179},{"className":2178},[],[2180],{"type":37,"value":2181},"platform = 'iOS'",{"type":32,"tag":33,"props":2183,"children":2184},{},[2185],{"type":37,"value":2186},"BigQuery accepte maximum 4 colonnes de clustering. L'ordre compte : placez la colonne la plus filtrée en premier.",{"type":32,"tag":33,"props":2188,"children":2189},{},[2190,2195,2197,2202],{"type":32,"tag":652,"props":2191,"children":2192},{},[2193],{"type":37,"value":2194},"BI Engine :",{"type":37,"value":2196}," La couche cache in-memory de BigQuery. Si vous réservez 100 GB BI Engine, les tables fréquemment consultées restent en RAM. ",{"type":32,"tag":40,"props":2198,"children":2200},{"className":2199},[],[2201],{"type":37,"value":1937},{"type":37,"value":2203}," fait 50 MB, reste entièrement dans BI Engine. Un scan cache = zéro scan facturé. Coût : 100 GB = $100\u002Fmois. Bénéfice : économies sur 10 TB de scan = $62,50. ROI positif.",{"type":32,"tag":529,"props":2205,"children":2207},{"id":2206},"fonctions-dapproximation-métriques-non-critiques",[2208],{"type":37,"value":2209},"Fonctions d'Approximation : Métriques Non-Critiques",{"type":32,"tag":33,"props":2211,"children":2212},{},[2213,2215,2221],{"type":37,"value":2214},"Certaines métriques cohort exigent de l'exactitude (",{"type":32,"tag":40,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":37,"value":2220},"COUNT(DISTINCT user_id)",{"type":37,"value":2222},"), d'autres tolèrent l'approximation (durée médiane de session, percentiles).",{"type":32,"tag":33,"props":2224,"children":2225},{},[2226],{"type":37,"value":2227},"Les fonctions approximatives BigQuery :",{"type":32,"tag":902,"props":2229,"children":2230},{},[2231,2242,2253],{"type":32,"tag":648,"props":2232,"children":2233},{},[2234,2240],{"type":32,"tag":40,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":37,"value":2239},"APPROX_COUNT_DISTINCT(user_id)",{"type":37,"value":2241}," → marge d'erreur 2 %, 10× plus rapide",{"type":32,"tag":648,"props":2243,"children":2244},{},[2245,2251],{"type":32,"tag":40,"props":2246,"children":2248},{"className":2247},[],[2249],{"type":37,"value":2250},"APPROX_QUANTILES(value, 100)[OFFSET(50)]",{"type":37,"value":2252}," → médiane, ~1 % d'erreur",{"type":32,"tag":648,"props":2254,"children":2255},{},[2256,2262],{"type":32,"tag":40,"props":2257,"children":2259},{"className":2258},[],[2260],{"type":37,"value":2261},"APPROX_TOP_COUNT(event_name, 10)",{"type":37,"value":2263}," → les 10 événements les plus fréquents",{"type":32,"tag":33,"props":2265,"children":2266},{},[2267,2269,2275,2277,2283],{"type":37,"value":2268},"Exemple : pour 50M utilisateurs, ",{"type":32,"tag":40,"props":2270,"children":2272},{"className":2271},[],[2273],{"type":37,"value":2274},"COUNT(DISTINCT ...)",{"type":37,"value":2276}," exact prend 8 secondes, ",{"type":32,"tag":40,"props":2278,"children":2280},{"className":2279},[],[2281],{"type":37,"value":2282},"APPROX_COUNT_DISTINCT",{"type":37,"value":2284}," prend 800 ms. Pour un dashboard avec filtres temps réel, utilisez l'approximation ; pour les rapports finaux, l'exact.",{"type":32,"tag":49,"props":2286,"children":2288},{"id":2287},"stratégie-de-mise-à-jour-incrémentale-event-time-vs-processing-time",[2289],{"type":37,"value":2290},"Stratégie de Mise à Jour Incrémentale : Event-Time vs Processing-Time",{"type":32,"tag":33,"props":2292,"children":2293},{},[2294,2296,2301],{"type":37,"value":2295},"Quand ",{"type":32,"tag":40,"props":2297,"children":2299},{"className":2298},[],[2300],{"type":37,"value":1209},{"type":37,"value":2302}," se renouvelle quotidiennement, quels événements traiter ? Il y a deux timestamps :",{"type":32,"tag":644,"props":2304,"children":2305},{},[2306,2316],{"type":32,"tag":648,"props":2307,"children":2308},{},[2309,2314],{"type":32,"tag":652,"props":2310,"children":2311},{},[2312],{"type":37,"value":2313},"event_time :",{"type":37,"value":2315}," Moment où l'utilisateur a déclenché l'événement (côté client)",{"type":32,"tag":648,"props":2317,"children":2318},{},[2319,2324],{"type":32,"tag":652,"props":2320,"children":2321},{},[2322],{"type":37,"value":2323},"_PARTITIONTIME :",{"type":37,"value":2325}," Moment où BigQuery a stocké l'événement (côté serveur)",{"type":32,"tag":33,"props":2327,"children":2328},{},[2329,2331,2336],{"type":37,"value":2330},"Une mise à jour incrémentale avec ",{"type":32,"tag":40,"props":2332,"children":2334},{"className":2333},[],[2335],{"type":37,"value":73},{"type":37,"value":2154},{"type":32,"tag":84,"props":2338,"children":2340},{"className":86,"code":2339,"language":88,"meta":16,"style":16},"WHERE event_time > (SELECT MAX(event_time) FROM cohort_assignments)\n",[2341],{"type":32,"tag":40,"props":2342,"children":2343},{"__ignoreMap":16},[2344],{"type":32,"tag":94,"props":2345,"children":2346},{"class":96,"line":97},[2347,2351,2355,2359,2363,2367,2371,2375,2379],{"type":32,"tag":94,"props":2348,"children":2349},{"style":101},[2350],{"type":37,"value":866},{"type":32,"tag":94,"props":2352,"children":2353},{"style":107},[2354],{"type":37,"value":871},{"type":32,"tag":94,"props":2356,"children":2357},{"style":101},[2358],{"type":37,"value":1501},{"type":32,"tag":94,"props":2360,"children":2361},{"style":107},[2362],{"type":37,"value":1506},{"type":32,"tag":94,"props":2364,"children":2365},{"style":101},[2366],{"type":37,"value":471},{"type":32,"tag":94,"props":2368,"children":2369},{"style":137},[2370],{"type":37,"value":1515},{"type":32,"tag":94,"props":2372,"children":2373},{"style":107},[2374],{"type":37,"value":838},{"type":32,"tag":94,"props":2376,"children":2377},{"style":101},[2378],{"type":37,"value":607},{"type":32,"tag":94,"props":2380,"children":2381},{"style":107},[2382],{"type":37,"value":2383}," cohort_assignments)\n",{"type":32,"tag":33,"props":2385,"children":2386},{},[2387,2392,2394,2399],{"type":32,"tag":652,"props":2388,"children":2389},{},[2390],{"type":37,"value":2391},"Problème :",{"type":37,"value":2393}," Événements en retard. L'utilisateur reste offline 3 jours, l'événement arrive par batch upload. Si ",{"type":32,"tag":40,"props":2395,"children":2397},{"className":2396},[],[2398],{"type":37,"value":73},{"type":37,"value":2400}," remonte à 3 jours, la requête incrémentale le rate.",{"type":32,"tag":33,"props":2402,"children":2403},{},[2404,2405,2411],{"type":37,"value":2330},{"type":32,"tag":40,"props":2406,"children":2408},{"className":2407},[],[2409],{"type":37,"value":2410},"_PARTITIONTIME",{"type":37,"value":2154},{"type":32,"tag":84,"props":2413,"children":2415},{"className":86,"code":2414,"language":88,"meta":16,"style":16},"WHERE _PARTITIONTIME > CURRENT_DATE() - 7\n",[2416],{"type":32,"tag":40,"props":2417,"children":2418},{"__ignoreMap":16},[2419],{"type":32,"tag":94,"props":2420,"children":2421},{"class":96,"line":97},[2422,2426,2431,2435,2440,2445],{"type":32,"tag":94,"props":2423,"children":2424},{"style":101},[2425],{"type":37,"value":866},{"type":32,"tag":94,"props":2427,"children":2428},{"style":107},[2429],{"type":37,"value":2430}," _PARTITIONTIME ",{"type":32,"tag":94,"props":2432,"children":2433},{"style":101},[2434],{"type":37,"value":1501},{"type":32,"tag":94,"props":2436,"children":2437},{"style":107},[2438],{"type":37,"value":2439}," CURRENT_DATE() ",{"type":32,"tag":94,"props":2441,"children":2442},{"style":101},[2443],{"type":37,"value":2444},"-",{"type":32,"tag":94,"props":2446,"children":2447},{"style":137},[2448],{"type":37,"value":2449}," 7\n",{"type":32,"tag":33,"props":2451,"children":2452},{},[2453,2458,2460,2465],{"type":32,"tag":652,"props":2454,"children":2455},{},[2456],{"type":37,"value":2457},"Avantage :",{"type":37,"value":2459}," Retraite les 7 derniers jours à chaque cycle, capture les événements tardifs.\n",{"type":32,"tag":652,"props":2461,"children":2462},{},[2463],{"type":37,"value":2464},"Coût :",{"type":37,"value":2466}," 7 jours de données d'événements = ~14 GB scannés par jour (vs 2 GB).",{"type":32,"tag":33,"props":2468,"children":2469},{},[2470,2472,2477,2479,2484],{"type":37,"value":2471},"Tradeoff : Si les événements tardifs \u003C 1 %, utilisez ",{"type":32,"tag":40,"props":2473,"children":2475},{"className":2474},[],[2476],{"type":37,"value":73},{"type":37,"value":2478},", scan bas. Pour une app mobile où les événements tardifs ~5 %, appliquez ",{"type":32,"tag":40,"props":2480,"children":2482},{"className":2481},[],[2483],{"type":37,"value":2410},{"type":37,"value":2485}," avec un lookback de 3 jours.",{"type":32,"tag":49,"props":2487,"children":2489},{"id":2488},"segmentation-de-cohort-filtres-dynamiques-vs-dimensions-statiques",[2490],{"type":37,"value":2491},"Segmentation de Cohort : Filtres Dynamiques vs Dimensions Statiques",{"type":32,"tag":33,"props":2493,"children":2494},{},[2495],{"type":37,"value":2496},"L'utilisateur demande un filtre au dashboard : « Rétention cohort iOS ». Deux méthodes :",{"type":32,"tag":33,"props":2498,"children":2499},{},[2500],{"type":32,"tag":652,"props":2501,"children":2502},{},[2503],{"type":37,"value":2504},"Méthode 1 : Filtre au moment de la requête",{"type":32,"tag":84,"props":2506,"children":2508},{"className":86,"code":2507,"language":88,"meta":16,"style":16},"SELECT cohort_week, weeks_since, active_users\nFROM cohort_retention_weekly\nWHERE user_id IN (SELECT user_id FROM users WHERE platform = 'iOS');\n",[2509],{"type":32,"tag":40,"props":2510,"children":2511},{"__ignoreMap":16},[2512,2524,2535],{"type":32,"tag":94,"props":2513,"children":2514},{"class":96,"line":97},[2515,2519],{"type":32,"tag":94,"props":2516,"children":2517},{"style":101},[2518],{"type":37,"value":471},{"type":32,"tag":94,"props":2520,"children":2521},{"style":107},[2522],{"type":37,"value":2523}," cohort_week, weeks_since, active_users\n",{"type":32,"tag":94,"props":2525,"children":2526},{"class":96,"line":123},[2527,2531],{"type":32,"tag":94,"props":2528,"children":2529},{"style":101},[2530],{"type":37,"value":607},{"type":32,"tag":94,"props":2532,"children":2533},{"style":107},[2534],{"type":37,"value":1601},{"type":32,"tag":94,"props":2536,"children":2537},{"class":96,"line":167},[2538,2542,2547,2552,2556,2560,2564,2568,2573,2577,2582,2586,2591],{"type":32,"tag":94,"props":2539,"children":2540},{"style":101},[2541],{"type":37,"value":866},{"type":32,"tag":94,"props":2543,"children":2544},{"style":107},[2545],{"type":37,"value":2546}," user_id ",{"type":32,"tag":94,"props":2548,"children":2549},{"style":101},[2550],{"type":37,"value":2551},"IN",{"type":32,"tag":94,"props":2553,"children":2554},{"style":107},[2555],{"type":37,"value":1506},{"type":32,"tag":94,"props":2557,"children":2558},{"style":101},[2559],{"type":37,"value":471},{"type":32,"tag":94,"props":2561,"children":2562},{"style":107},[2563],{"type":37,"value":2546},{"type":32,"tag":94,"props":2565,"children":2566},{"style":101},[2567],{"type":37,"value":607},{"type":32,"tag":94,"props":2569,"children":2570},{"style":107},[2571],{"type":37,"value":2572}," users ",{"type":32,"tag":94,"props":2574,"children":2575},{"style":101},[2576],{"type":37,"value":866},{"type":32,"tag":94,"props":2578,"children":2579},{"style":107},[2580],{"type":37,"value":2581}," platform ",{"type":32,"tag":94,"props":2583,"children":2584},{"style":101},[2585],{"type":37,"value":1270},{"type":32,"tag":94,"props":2587,"children":2588},{"style":879},[2589],{"type":37,"value":2590}," 'iOS'",{"type":32,"tag":94,"props":2592,"children":2593},{"style":107},[2594],{"type":37,"value":2595},");\n",{"type":32,"tag":33,"props":2597,"children":2598},{},[2599,2603,2605,2611],{"type":32,"tag":652,"props":2600,"children":2601},{},[2602],{"type":37,"value":2391},{"type":37,"value":2604}," La subquery scanne ",{"type":32,"tag":40,"props":2606,"children":2608},{"className":2607},[],[2609],{"type":37,"value":2610},"users",{"type":37,"value":2612}," à chaque fois. 50M utilisateurs = 1 GB scannés. Dashboard rafraîchit 100 fois = 100 GB.",{"type":32,"tag":33,"props":2614,"children":2615},{},[2616],{"type":32,"tag":652,"props":2617,"children":2618},{},[2619],{"type":37,"value":2620},"Méthode 2 : Pré-calcul des dimensions",{"type":32,"tag":84,"props":2622,"children":2623},{"className":86,"code":16,"language":88,"meta":16,"style":16},[2624],{"type":32,"tag":40,"props":2625,"children":2626},{"__ignoreMap":16},[2627],{"type":32,"tag":94,"props":2628,"children":2629},{"class":96,"line":97},[],{"type":32,"tag":2631,"props":2632,"children":2633},"style",{},[2634],{"type":37,"value":2635},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":167,"depth":167,"links":2637},[2638,2641,2644,2647,2650,2651],{"id":51,"depth":123,"text":54,"children":2639},[2640],{"id":531,"depth":167,"text":534},{"id":684,"depth":123,"text":687,"children":2642},[2643],{"id":1221,"depth":167,"text":1224},{"id":1558,"depth":123,"text":1561,"children":2645},[2646],{"id":1972,"depth":167,"text":1975},{"id":2080,"depth":123,"text":2083,"children":2648},[2649],{"id":2206,"depth":167,"text":2209},{"id":2287,"depth":123,"text":2290},{"id":2488,"depth":123,"text":2491},"markdown","content:fr:data:architecture-table-cohort-retention-optimisation-production.md","content","fr\u002Fdata\u002Farchitecture-table-cohort-retention-optimisation-production.md","fr\u002Fdata\u002Farchitecture-table-cohort-retention-optimisation-production","md",1785967483520]