[{"data":1,"prerenderedAt":2689},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fit\u002Fdata\u002Farchitettura-tabella-cohort-retention-production":13},{"i18nKey":4,"paths":5},"data-007-2026-05",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fcohort-tabellenstruktur","\u002Fen\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fes\u002Fdata\u002Farquitectura-tabla-cohort","\u002Ffr\u002Fdata\u002Fcohort-table-architecture","\u002Fit\u002Fdata\u002Farchitettura-tabella-cohort-retention-production","\u002Fru\u002Fdata\u002Fcohort-tablesql-architecture-production-retention","\u002Ftr\u002Fdata\u002Fcohort-tablo-mimarisi-retention-analizinin-productionda-olceklenmesi",{"_path":10,"_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":2683,"_id":2684,"_source":2685,"_file":2686,"_stem":2687,"_extension":2688},"data",false,"","Architettura Tabella Cohort: Scalare l'Analisi di Retention in Production","Materialized views, partitioning e query cost optimization per cohort analysis su milioni di utenti: architettura BigQuery pronta per la produzione.","2026-05-22",[21,22,23,24,25],"cohort-analysis","bigquery","materialized-views","retention-engineering","query-optimization",8,"Roibase",{"type":29,"children":30,"toc":2673},"root",[31,39,46,51,531,544,550,578,670,675,681,686,848,860,865,1195,1200,1206,1211,1251,1256,2139,2155,2161,2166,2204,2209,2296,2301,2307,2312,2326,2331,2421,2426,2432,2437,2470,2484,2490,2495,2528,2533,2657,2662,2667],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":37,"value":38},"text","L'analisi di retention è uno dei metodi più potenti per comprendere il comportamento degli utenti. Ma a scala reale — milioni di eventi al giorno, centinaia di migliaia di utenti — le query SQL ingenue scadono in 30 secondi o consumano la capacità di slot. La retention analysis sostenibile in produzione richiede di ottimizzare l'architettura delle tabelle per il motore di query. In questo articolo ti mostriamo come scalare le tabelle cohort su BigQuery utilizzando materialized view, partitioning e strategie di refresh incrementale.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"perché-la-query-cohort-ingenua-fallisce",[44],{"type":37,"value":45},"Perché la Query Cohort Ingenua Fallisce",{"type":32,"tag":33,"props":47,"children":48},{},[49],{"type":37,"value":50},"L'analisi cohort classica funziona così: trova la data della prima attività dell'utente (cohort_date), calcola tutte le attività successive come \"giorno N\" rispetto a quella data, aggrega il tasso di retention per gruppo. La seguente query SQL è logicamente corretta ma non funziona in produzione:",{"type":32,"tag":52,"props":53,"children":57},"pre",{"className":54,"code":55,"language":56,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","WITH first_event AS (\n  SELECT user_id, MIN(DATE(event_timestamp)) AS cohort_date\n  FROM `project.dataset.events`\n  GROUP BY user_id\n),\ndaily_activity AS (\n  SELECT e.user_id, DATE(e.event_timestamp) AS activity_date\n  FROM `project.dataset.events` e\n  GROUP BY 1,2\n)\nSELECT \n  f.cohort_date,\n  DATE_DIFF(d.activity_date, f.cohort_date, DAY) AS day_n,\n  COUNT(DISTINCT d.user_id) AS retained_users\nFROM first_event f\nJOIN daily_activity d USING(user_id)\nGROUP BY 1,2\nORDER BY 1,2;\n","sql",[58],{"type":32,"tag":59,"props":60,"children":61},"code",{"__ignoreMap":16},[62,90,134,149,163,172,189,253,270,293,302,316,339,401,445,459,483,504],{"type":32,"tag":63,"props":64,"children":67},"span",{"class":65,"line":66},"line",1,[68,74,80,85],{"type":32,"tag":63,"props":69,"children":71},{"style":70},"--shiki-default:#F97583",[72],{"type":37,"value":73},"WITH",{"type":32,"tag":63,"props":75,"children":77},{"style":76},"--shiki-default:#E1E4E8",[78],{"type":37,"value":79}," first_event ",{"type":32,"tag":63,"props":81,"children":82},{"style":70},[83],{"type":37,"value":84},"AS",{"type":32,"tag":63,"props":86,"children":87},{"style":76},[88],{"type":37,"value":89}," (\n",{"type":32,"tag":63,"props":91,"children":93},{"class":65,"line":92},2,[94,99,104,110,115,120,125,129],{"type":32,"tag":63,"props":95,"children":96},{"style":70},[97],{"type":37,"value":98},"  SELECT",{"type":32,"tag":63,"props":100,"children":101},{"style":76},[102],{"type":37,"value":103}," user_id, ",{"type":32,"tag":63,"props":105,"children":107},{"style":106},"--shiki-default:#79B8FF",[108],{"type":37,"value":109},"MIN",{"type":32,"tag":63,"props":111,"children":112},{"style":76},[113],{"type":37,"value":114},"(",{"type":32,"tag":63,"props":116,"children":117},{"style":70},[118],{"type":37,"value":119},"DATE",{"type":32,"tag":63,"props":121,"children":122},{"style":76},[123],{"type":37,"value":124},"(event_timestamp)) ",{"type":32,"tag":63,"props":126,"children":127},{"style":70},[128],{"type":37,"value":84},{"type":32,"tag":63,"props":130,"children":131},{"style":76},[132],{"type":37,"value":133}," cohort_date\n",{"type":32,"tag":63,"props":135,"children":137},{"class":65,"line":136},3,[138,143],{"type":32,"tag":63,"props":139,"children":140},{"style":70},[141],{"type":37,"value":142},"  FROM",{"type":32,"tag":63,"props":144,"children":146},{"style":145},"--shiki-default:#9ECBFF",[147],{"type":37,"value":148}," `project.dataset.events`\n",{"type":32,"tag":63,"props":150,"children":152},{"class":65,"line":151},4,[153,158],{"type":32,"tag":63,"props":154,"children":155},{"style":70},[156],{"type":37,"value":157},"  GROUP BY",{"type":32,"tag":63,"props":159,"children":160},{"style":76},[161],{"type":37,"value":162}," user_id\n",{"type":32,"tag":63,"props":164,"children":166},{"class":65,"line":165},5,[167],{"type":32,"tag":63,"props":168,"children":169},{"style":76},[170],{"type":37,"value":171},"),\n",{"type":32,"tag":63,"props":173,"children":175},{"class":65,"line":174},6,[176,181,185],{"type":32,"tag":63,"props":177,"children":178},{"style":76},[179],{"type":37,"value":180},"daily_activity ",{"type":32,"tag":63,"props":182,"children":183},{"style":70},[184],{"type":37,"value":84},{"type":32,"tag":63,"props":186,"children":187},{"style":76},[188],{"type":37,"value":89},{"type":32,"tag":63,"props":190,"children":192},{"class":65,"line":191},7,[193,197,202,207,212,217,221,225,230,234,239,244,248],{"type":32,"tag":63,"props":194,"children":195},{"style":70},[196],{"type":37,"value":98},{"type":32,"tag":63,"props":198,"children":199},{"style":106},[200],{"type":37,"value":201}," e",{"type":32,"tag":63,"props":203,"children":204},{"style":76},[205],{"type":37,"value":206},".",{"type":32,"tag":63,"props":208,"children":209},{"style":106},[210],{"type":37,"value":211},"user_id",{"type":32,"tag":63,"props":213,"children":214},{"style":76},[215],{"type":37,"value":216},", ",{"type":32,"tag":63,"props":218,"children":219},{"style":70},[220],{"type":37,"value":119},{"type":32,"tag":63,"props":222,"children":223},{"style":76},[224],{"type":37,"value":114},{"type":32,"tag":63,"props":226,"children":227},{"style":106},[228],{"type":37,"value":229},"e",{"type":32,"tag":63,"props":231,"children":232},{"style":76},[233],{"type":37,"value":206},{"type":32,"tag":63,"props":235,"children":236},{"style":106},[237],{"type":37,"value":238},"event_timestamp",{"type":32,"tag":63,"props":240,"children":241},{"style":76},[242],{"type":37,"value":243},") ",{"type":32,"tag":63,"props":245,"children":246},{"style":70},[247],{"type":37,"value":84},{"type":32,"tag":63,"props":249,"children":250},{"style":76},[251],{"type":37,"value":252}," activity_date\n",{"type":32,"tag":63,"props":254,"children":255},{"class":65,"line":26},[256,260,265],{"type":32,"tag":63,"props":257,"children":258},{"style":70},[259],{"type":37,"value":142},{"type":32,"tag":63,"props":261,"children":262},{"style":145},[263],{"type":37,"value":264}," `project.dataset.events`",{"type":32,"tag":63,"props":266,"children":267},{"style":76},[268],{"type":37,"value":269}," e\n",{"type":32,"tag":63,"props":271,"children":273},{"class":65,"line":272},9,[274,278,283,288],{"type":32,"tag":63,"props":275,"children":276},{"style":70},[277],{"type":37,"value":157},{"type":32,"tag":63,"props":279,"children":280},{"style":106},[281],{"type":37,"value":282}," 1",{"type":32,"tag":63,"props":284,"children":285},{"style":76},[286],{"type":37,"value":287},",",{"type":32,"tag":63,"props":289,"children":290},{"style":106},[291],{"type":37,"value":292},"2\n",{"type":32,"tag":63,"props":294,"children":296},{"class":65,"line":295},10,[297],{"type":32,"tag":63,"props":298,"children":299},{"style":76},[300],{"type":37,"value":301},")\n",{"type":32,"tag":63,"props":303,"children":305},{"class":65,"line":304},11,[306,311],{"type":32,"tag":63,"props":307,"children":308},{"style":70},[309],{"type":37,"value":310},"SELECT",{"type":32,"tag":63,"props":312,"children":313},{"style":76},[314],{"type":37,"value":315}," \n",{"type":32,"tag":63,"props":317,"children":319},{"class":65,"line":318},12,[320,325,329,334],{"type":32,"tag":63,"props":321,"children":322},{"style":106},[323],{"type":37,"value":324},"  f",{"type":32,"tag":63,"props":326,"children":327},{"style":76},[328],{"type":37,"value":206},{"type":32,"tag":63,"props":330,"children":331},{"style":106},[332],{"type":37,"value":333},"cohort_date",{"type":32,"tag":63,"props":335,"children":336},{"style":76},[337],{"type":37,"value":338},",\n",{"type":32,"tag":63,"props":340,"children":342},{"class":65,"line":341},13,[343,348,353,357,362,366,371,375,379,383,388,392,396],{"type":32,"tag":63,"props":344,"children":345},{"style":76},[346],{"type":37,"value":347},"  DATE_DIFF(",{"type":32,"tag":63,"props":349,"children":350},{"style":106},[351],{"type":37,"value":352},"d",{"type":32,"tag":63,"props":354,"children":355},{"style":76},[356],{"type":37,"value":206},{"type":32,"tag":63,"props":358,"children":359},{"style":106},[360],{"type":37,"value":361},"activity_date",{"type":32,"tag":63,"props":363,"children":364},{"style":76},[365],{"type":37,"value":216},{"type":32,"tag":63,"props":367,"children":368},{"style":106},[369],{"type":37,"value":370},"f",{"type":32,"tag":63,"props":372,"children":373},{"style":76},[374],{"type":37,"value":206},{"type":32,"tag":63,"props":376,"children":377},{"style":106},[378],{"type":37,"value":333},{"type":32,"tag":63,"props":380,"children":381},{"style":76},[382],{"type":37,"value":216},{"type":32,"tag":63,"props":384,"children":385},{"style":70},[386],{"type":37,"value":387},"DAY",{"type":32,"tag":63,"props":389,"children":390},{"style":76},[391],{"type":37,"value":243},{"type":32,"tag":63,"props":393,"children":394},{"style":70},[395],{"type":37,"value":84},{"type":32,"tag":63,"props":397,"children":398},{"style":76},[399],{"type":37,"value":400}," day_n,\n",{"type":32,"tag":63,"props":402,"children":404},{"class":65,"line":403},14,[405,410,414,419,424,428,432,436,440],{"type":32,"tag":63,"props":406,"children":407},{"style":106},[408],{"type":37,"value":409},"  COUNT",{"type":32,"tag":63,"props":411,"children":412},{"style":76},[413],{"type":37,"value":114},{"type":32,"tag":63,"props":415,"children":416},{"style":70},[417],{"type":37,"value":418},"DISTINCT",{"type":32,"tag":63,"props":420,"children":421},{"style":106},[422],{"type":37,"value":423}," d",{"type":32,"tag":63,"props":425,"children":426},{"style":76},[427],{"type":37,"value":206},{"type":32,"tag":63,"props":429,"children":430},{"style":106},[431],{"type":37,"value":211},{"type":32,"tag":63,"props":433,"children":434},{"style":76},[435],{"type":37,"value":243},{"type":32,"tag":63,"props":437,"children":438},{"style":70},[439],{"type":37,"value":84},{"type":32,"tag":63,"props":441,"children":442},{"style":76},[443],{"type":37,"value":444}," retained_users\n",{"type":32,"tag":63,"props":446,"children":448},{"class":65,"line":447},15,[449,454],{"type":32,"tag":63,"props":450,"children":451},{"style":70},[452],{"type":37,"value":453},"FROM",{"type":32,"tag":63,"props":455,"children":456},{"style":76},[457],{"type":37,"value":458}," first_event f\n",{"type":32,"tag":63,"props":460,"children":462},{"class":65,"line":461},16,[463,468,473,478],{"type":32,"tag":63,"props":464,"children":465},{"style":70},[466],{"type":37,"value":467},"JOIN",{"type":32,"tag":63,"props":469,"children":470},{"style":76},[471],{"type":37,"value":472}," daily_activity d ",{"type":32,"tag":63,"props":474,"children":475},{"style":70},[476],{"type":37,"value":477},"USING",{"type":32,"tag":63,"props":479,"children":480},{"style":76},[481],{"type":37,"value":482},"(user_id)\n",{"type":32,"tag":63,"props":484,"children":486},{"class":65,"line":485},17,[487,492,496,500],{"type":32,"tag":63,"props":488,"children":489},{"style":70},[490],{"type":37,"value":491},"GROUP BY",{"type":32,"tag":63,"props":493,"children":494},{"style":106},[495],{"type":37,"value":282},{"type":32,"tag":63,"props":497,"children":498},{"style":76},[499],{"type":37,"value":287},{"type":32,"tag":63,"props":501,"children":502},{"style":106},[503],{"type":37,"value":292},{"type":32,"tag":63,"props":505,"children":507},{"class":65,"line":506},18,[508,513,517,521,526],{"type":32,"tag":63,"props":509,"children":510},{"style":70},[511],{"type":37,"value":512},"ORDER BY",{"type":32,"tag":63,"props":514,"children":515},{"style":106},[516],{"type":37,"value":282},{"type":32,"tag":63,"props":518,"children":519},{"style":76},[520],{"type":37,"value":287},{"type":32,"tag":63,"props":522,"children":523},{"style":106},[524],{"type":37,"value":525},"2",{"type":32,"tag":63,"props":527,"children":528},{"style":76},[529],{"type":37,"value":530},";\n",{"type":32,"tag":33,"props":532,"children":533},{},[534,536,542],{"type":37,"value":535},"Questa query ha due grandi problemi: (1) la tabella ",{"type":32,"tag":59,"props":537,"children":539},{"className":538},[],[540],{"type":37,"value":541},"events",{"type":37,"value":543}," viene scansionata completamente ogni volta — nessun partition pruning, (2) per ogni cohort_date tutti gli utenti e tutte le loro attività vengono joinati — rischio di esplosione cartesiana. Su 100M eventi questa query elabora 400GB di dati e termina in 2 minuti, ma per un refresh giornaliero questo non è sostenibile. La fattura di BigQuery triplica o quadruplica entro fine mese.",{"type":32,"tag":40,"props":545,"children":547},{"id":546},"ridurre-il-carico-di-filtro-con-partitioned-base-table",[548],{"type":37,"value":549},"Ridurre il Carico di Filtro con Partitioned Base Table",{"type":32,"tag":33,"props":551,"children":552},{},[553,555,560,562,568,570,576],{"type":37,"value":554},"Il primo passo è partizionare la tabella ",{"type":32,"tag":59,"props":556,"children":558},{"className":557},[],[559],{"type":37,"value":541},{"type":37,"value":561}," per ",{"type":32,"tag":59,"props":563,"children":565},{"className":564},[],[566],{"type":37,"value":567},"DATE(event_timestamp)",{"type":37,"value":569},". In questo modo, quando aggiungi una clausola ",{"type":32,"tag":59,"props":571,"children":573},{"className":572},[],[574],{"type":37,"value":575},"WHERE DATE(event_timestamp) BETWEEN X AND Y",{"type":37,"value":577}," alla query, solo le partition rilevanti vengono scansionate:",{"type":32,"tag":52,"props":579,"children":581},{"className":54,"code":580,"language":56,"meta":16,"style":16},"CREATE TABLE `project.dataset.events`\nPARTITION BY DATE(event_timestamp)\nCLUSTER BY user_id, event_name\nAS SELECT * FROM ...;\n",[582],{"type":32,"tag":59,"props":583,"children":584},{"__ignoreMap":16},[585,602,625,643],{"type":32,"tag":63,"props":586,"children":587},{"class":65,"line":66},[588,593,598],{"type":32,"tag":63,"props":589,"children":590},{"style":70},[591],{"type":37,"value":592},"CREATE",{"type":32,"tag":63,"props":594,"children":595},{"style":70},[596],{"type":37,"value":597}," TABLE",{"type":32,"tag":63,"props":599,"children":600},{"style":145},[601],{"type":37,"value":148},{"type":32,"tag":63,"props":603,"children":604},{"class":65,"line":92},[605,610,615,620],{"type":32,"tag":63,"props":606,"children":607},{"style":70},[608],{"type":37,"value":609},"PARTITION",{"type":32,"tag":63,"props":611,"children":612},{"style":70},[613],{"type":37,"value":614}," BY",{"type":32,"tag":63,"props":616,"children":617},{"style":70},[618],{"type":37,"value":619}," DATE",{"type":32,"tag":63,"props":621,"children":622},{"style":76},[623],{"type":37,"value":624},"(event_timestamp)\n",{"type":32,"tag":63,"props":626,"children":627},{"class":65,"line":136},[628,633,638],{"type":32,"tag":63,"props":629,"children":630},{"style":76},[631],{"type":37,"value":632},"CLUSTER ",{"type":32,"tag":63,"props":634,"children":635},{"style":70},[636],{"type":37,"value":637},"BY",{"type":32,"tag":63,"props":639,"children":640},{"style":76},[641],{"type":37,"value":642}," user_id, event_name\n",{"type":32,"tag":63,"props":644,"children":645},{"class":65,"line":151},[646,650,655,660,665],{"type":32,"tag":63,"props":647,"children":648},{"style":70},[649],{"type":37,"value":84},{"type":32,"tag":63,"props":651,"children":652},{"style":70},[653],{"type":37,"value":654}," SELECT",{"type":32,"tag":63,"props":656,"children":657},{"style":70},[658],{"type":37,"value":659}," *",{"type":32,"tag":63,"props":661,"children":662},{"style":70},[663],{"type":37,"value":664}," FROM",{"type":32,"tag":63,"props":666,"children":667},{"style":76},[668],{"type":37,"value":669}," ...;\n",{"type":32,"tag":33,"props":671,"children":672},{},[673],{"type":37,"value":674},"L'aggiunta del clustering su (user_id, event_name) garantisce che gli eventi dello stesso utente siano memorizzati fisicamente in blocchi vicini — la performance del join aumenta del 30-50%. Tuttavia, ciò da solo non è sufficiente; la logica di calcolo cohort viene rieseguita in ogni query. È qui che entra in gioco la materialized view.",{"type":32,"tag":40,"props":676,"children":678},{"id":677},"materialized-view-tabella-cohort-incrementale",[679],{"type":37,"value":680},"Materialized View: Tabella Cohort Incrementale",{"type":32,"tag":33,"props":682,"children":683},{},[684],{"type":37,"value":685},"Le materialized view di BigQuery memorizzano il risultato della query fisicamente e si aggiornano automaticamente quando la tabella base cambia. Per l'analisi cohort usiamo questa struttura:",{"type":32,"tag":52,"props":687,"children":689},{"className":54,"code":688,"language":56,"meta":16,"style":16},"CREATE MATERIALIZED VIEW `project.dataset.user_cohorts`\nPARTITION BY cohort_date\nCLUSTER BY user_id\nAS\nSELECT \n  user_id,\n  MIN(DATE(event_timestamp)) AS cohort_date,\n  COUNT(*) AS first_day_events\nFROM `project.dataset.events`\nGROUP BY user_id;\n",[690],{"type":32,"tag":59,"props":691,"children":692},{"__ignoreMap":16},[693,710,725,740,748,759,767,796,825,836],{"type":32,"tag":63,"props":694,"children":695},{"class":65,"line":66},[696,700,705],{"type":32,"tag":63,"props":697,"children":698},{"style":70},[699],{"type":37,"value":592},{"type":32,"tag":63,"props":701,"children":702},{"style":76},[703],{"type":37,"value":704}," MATERIALIZED VIEW ",{"type":32,"tag":63,"props":706,"children":707},{"style":145},[708],{"type":37,"value":709},"`project.dataset.user_cohorts`\n",{"type":32,"tag":63,"props":711,"children":712},{"class":65,"line":92},[713,717,721],{"type":32,"tag":63,"props":714,"children":715},{"style":70},[716],{"type":37,"value":609},{"type":32,"tag":63,"props":718,"children":719},{"style":70},[720],{"type":37,"value":614},{"type":32,"tag":63,"props":722,"children":723},{"style":76},[724],{"type":37,"value":133},{"type":32,"tag":63,"props":726,"children":727},{"class":65,"line":136},[728,732,736],{"type":32,"tag":63,"props":729,"children":730},{"style":76},[731],{"type":37,"value":632},{"type":32,"tag":63,"props":733,"children":734},{"style":70},[735],{"type":37,"value":637},{"type":32,"tag":63,"props":737,"children":738},{"style":76},[739],{"type":37,"value":162},{"type":32,"tag":63,"props":741,"children":742},{"class":65,"line":151},[743],{"type":32,"tag":63,"props":744,"children":745},{"style":70},[746],{"type":37,"value":747},"AS\n",{"type":32,"tag":63,"props":749,"children":750},{"class":65,"line":165},[751,755],{"type":32,"tag":63,"props":752,"children":753},{"style":70},[754],{"type":37,"value":310},{"type":32,"tag":63,"props":756,"children":757},{"style":76},[758],{"type":37,"value":315},{"type":32,"tag":63,"props":760,"children":761},{"class":65,"line":174},[762],{"type":32,"tag":63,"props":763,"children":764},{"style":76},[765],{"type":37,"value":766},"  user_id,\n",{"type":32,"tag":63,"props":768,"children":769},{"class":65,"line":191},[770,775,779,783,787,791],{"type":32,"tag":63,"props":771,"children":772},{"style":106},[773],{"type":37,"value":774},"  MIN",{"type":32,"tag":63,"props":776,"children":777},{"style":76},[778],{"type":37,"value":114},{"type":32,"tag":63,"props":780,"children":781},{"style":70},[782],{"type":37,"value":119},{"type":32,"tag":63,"props":784,"children":785},{"style":76},[786],{"type":37,"value":124},{"type":32,"tag":63,"props":788,"children":789},{"style":70},[790],{"type":37,"value":84},{"type":32,"tag":63,"props":792,"children":793},{"style":76},[794],{"type":37,"value":795}," cohort_date,\n",{"type":32,"tag":63,"props":797,"children":798},{"class":65,"line":26},[799,803,807,812,816,820],{"type":32,"tag":63,"props":800,"children":801},{"style":106},[802],{"type":37,"value":409},{"type":32,"tag":63,"props":804,"children":805},{"style":76},[806],{"type":37,"value":114},{"type":32,"tag":63,"props":808,"children":809},{"style":70},[810],{"type":37,"value":811},"*",{"type":32,"tag":63,"props":813,"children":814},{"style":76},[815],{"type":37,"value":243},{"type":32,"tag":63,"props":817,"children":818},{"style":70},[819],{"type":37,"value":84},{"type":32,"tag":63,"props":821,"children":822},{"style":76},[823],{"type":37,"value":824}," first_day_events\n",{"type":32,"tag":63,"props":826,"children":827},{"class":65,"line":272},[828,832],{"type":32,"tag":63,"props":829,"children":830},{"style":70},[831],{"type":37,"value":453},{"type":32,"tag":63,"props":833,"children":834},{"style":145},[835],{"type":37,"value":148},{"type":32,"tag":63,"props":837,"children":838},{"class":65,"line":295},[839,843],{"type":32,"tag":63,"props":840,"children":841},{"style":70},[842],{"type":37,"value":491},{"type":32,"tag":63,"props":844,"children":845},{"style":76},[846],{"type":37,"value":847}," user_id;\n",{"type":32,"tag":33,"props":849,"children":850},{},[851,853,859],{"type":37,"value":852},"Questa view calcola e memorizza una sola volta la data in cui ogni utente è stato visto per la prima volta (cohort_date). Quando arrivano nuovi eventi, BigQuery elabora solo il delta — nessuna scansione completa. La partizione per cohort_date consente il pruning nelle query di retention quando filtri con ",{"type":32,"tag":59,"props":854,"children":856},{"className":855},[],[857],{"type":37,"value":858},"WHERE cohort_date = '2026-05-01'",{"type":37,"value":206},{"type":32,"tag":33,"props":861,"children":862},{},[863],{"type":37,"value":864},"Ora la query di calcolo retention si riduce a:",{"type":32,"tag":52,"props":866,"children":868},{"className":54,"code":867,"language":56,"meta":16,"style":16},"SELECT \n  c.cohort_date,\n  DATE_DIFF(DATE(e.event_timestamp), c.cohort_date, DAY) AS day_n,\n  COUNT(DISTINCT e.user_id) AS retained_users\nFROM `project.dataset.user_cohorts` c\nJOIN `project.dataset.events` e \n  ON c.user_id = e.user_id \n  AND DATE(e.event_timestamp) >= c.cohort_date\nWHERE c.cohort_date BETWEEN '2026-05-01' AND '2026-05-15'\nGROUP BY 1,2;\n",[869],{"type":32,"tag":59,"props":870,"children":871},{"__ignoreMap":16},[872,883,903,968,1007,1024,1040,1082,1132,1172],{"type":32,"tag":63,"props":873,"children":874},{"class":65,"line":66},[875,879],{"type":32,"tag":63,"props":876,"children":877},{"style":70},[878],{"type":37,"value":310},{"type":32,"tag":63,"props":880,"children":881},{"style":76},[882],{"type":37,"value":315},{"type":32,"tag":63,"props":884,"children":885},{"class":65,"line":92},[886,891,895,899],{"type":32,"tag":63,"props":887,"children":888},{"style":106},[889],{"type":37,"value":890},"  c",{"type":32,"tag":63,"props":892,"children":893},{"style":76},[894],{"type":37,"value":206},{"type":32,"tag":63,"props":896,"children":897},{"style":106},[898],{"type":37,"value":333},{"type":32,"tag":63,"props":900,"children":901},{"style":76},[902],{"type":37,"value":338},{"type":32,"tag":63,"props":904,"children":905},{"class":65,"line":136},[906,910,914,918,922,926,930,935,940,944,948,952,956,960,964],{"type":32,"tag":63,"props":907,"children":908},{"style":76},[909],{"type":37,"value":347},{"type":32,"tag":63,"props":911,"children":912},{"style":70},[913],{"type":37,"value":119},{"type":32,"tag":63,"props":915,"children":916},{"style":76},[917],{"type":37,"value":114},{"type":32,"tag":63,"props":919,"children":920},{"style":106},[921],{"type":37,"value":229},{"type":32,"tag":63,"props":923,"children":924},{"style":76},[925],{"type":37,"value":206},{"type":32,"tag":63,"props":927,"children":928},{"style":106},[929],{"type":37,"value":238},{"type":32,"tag":63,"props":931,"children":932},{"style":76},[933],{"type":37,"value":934},"), ",{"type":32,"tag":63,"props":936,"children":937},{"style":106},[938],{"type":37,"value":939},"c",{"type":32,"tag":63,"props":941,"children":942},{"style":76},[943],{"type":37,"value":206},{"type":32,"tag":63,"props":945,"children":946},{"style":106},[947],{"type":37,"value":333},{"type":32,"tag":63,"props":949,"children":950},{"style":76},[951],{"type":37,"value":216},{"type":32,"tag":63,"props":953,"children":954},{"style":70},[955],{"type":37,"value":387},{"type":32,"tag":63,"props":957,"children":958},{"style":76},[959],{"type":37,"value":243},{"type":32,"tag":63,"props":961,"children":962},{"style":70},[963],{"type":37,"value":84},{"type":32,"tag":63,"props":965,"children":966},{"style":76},[967],{"type":37,"value":400},{"type":32,"tag":63,"props":969,"children":970},{"class":65,"line":151},[971,975,979,983,987,991,995,999,1003],{"type":32,"tag":63,"props":972,"children":973},{"style":106},[974],{"type":37,"value":409},{"type":32,"tag":63,"props":976,"children":977},{"style":76},[978],{"type":37,"value":114},{"type":32,"tag":63,"props":980,"children":981},{"style":70},[982],{"type":37,"value":418},{"type":32,"tag":63,"props":984,"children":985},{"style":106},[986],{"type":37,"value":201},{"type":32,"tag":63,"props":988,"children":989},{"style":76},[990],{"type":37,"value":206},{"type":32,"tag":63,"props":992,"children":993},{"style":106},[994],{"type":37,"value":211},{"type":32,"tag":63,"props":996,"children":997},{"style":76},[998],{"type":37,"value":243},{"type":32,"tag":63,"props":1000,"children":1001},{"style":70},[1002],{"type":37,"value":84},{"type":32,"tag":63,"props":1004,"children":1005},{"style":76},[1006],{"type":37,"value":444},{"type":32,"tag":63,"props":1008,"children":1009},{"class":65,"line":165},[1010,1014,1019],{"type":32,"tag":63,"props":1011,"children":1012},{"style":70},[1013],{"type":37,"value":453},{"type":32,"tag":63,"props":1015,"children":1016},{"style":145},[1017],{"type":37,"value":1018}," `project.dataset.user_cohorts`",{"type":32,"tag":63,"props":1020,"children":1021},{"style":76},[1022],{"type":37,"value":1023}," c\n",{"type":32,"tag":63,"props":1025,"children":1026},{"class":65,"line":174},[1027,1031,1035],{"type":32,"tag":63,"props":1028,"children":1029},{"style":70},[1030],{"type":37,"value":467},{"type":32,"tag":63,"props":1032,"children":1033},{"style":145},[1034],{"type":37,"value":264},{"type":32,"tag":63,"props":1036,"children":1037},{"style":76},[1038],{"type":37,"value":1039}," e \n",{"type":32,"tag":63,"props":1041,"children":1042},{"class":65,"line":191},[1043,1048,1053,1057,1061,1066,1070,1074,1078],{"type":32,"tag":63,"props":1044,"children":1045},{"style":70},[1046],{"type":37,"value":1047},"  ON",{"type":32,"tag":63,"props":1049,"children":1050},{"style":106},[1051],{"type":37,"value":1052}," c",{"type":32,"tag":63,"props":1054,"children":1055},{"style":76},[1056],{"type":37,"value":206},{"type":32,"tag":63,"props":1058,"children":1059},{"style":106},[1060],{"type":37,"value":211},{"type":32,"tag":63,"props":1062,"children":1063},{"style":70},[1064],{"type":37,"value":1065}," =",{"type":32,"tag":63,"props":1067,"children":1068},{"style":106},[1069],{"type":37,"value":201},{"type":32,"tag":63,"props":1071,"children":1072},{"style":76},[1073],{"type":37,"value":206},{"type":32,"tag":63,"props":1075,"children":1076},{"style":106},[1077],{"type":37,"value":211},{"type":32,"tag":63,"props":1079,"children":1080},{"style":76},[1081],{"type":37,"value":315},{"type":32,"tag":63,"props":1083,"children":1084},{"class":65,"line":26},[1085,1090,1094,1098,1102,1106,1110,1114,1119,1123,1127],{"type":32,"tag":63,"props":1086,"children":1087},{"style":70},[1088],{"type":37,"value":1089},"  AND",{"type":32,"tag":63,"props":1091,"children":1092},{"style":70},[1093],{"type":37,"value":619},{"type":32,"tag":63,"props":1095,"children":1096},{"style":76},[1097],{"type":37,"value":114},{"type":32,"tag":63,"props":1099,"children":1100},{"style":106},[1101],{"type":37,"value":229},{"type":32,"tag":63,"props":1103,"children":1104},{"style":76},[1105],{"type":37,"value":206},{"type":32,"tag":63,"props":1107,"children":1108},{"style":106},[1109],{"type":37,"value":238},{"type":32,"tag":63,"props":1111,"children":1112},{"style":76},[1113],{"type":37,"value":243},{"type":32,"tag":63,"props":1115,"children":1116},{"style":70},[1117],{"type":37,"value":1118},">=",{"type":32,"tag":63,"props":1120,"children":1121},{"style":106},[1122],{"type":37,"value":1052},{"type":32,"tag":63,"props":1124,"children":1125},{"style":76},[1126],{"type":37,"value":206},{"type":32,"tag":63,"props":1128,"children":1129},{"style":106},[1130],{"type":37,"value":1131},"cohort_date\n",{"type":32,"tag":63,"props":1133,"children":1134},{"class":65,"line":272},[1135,1140,1144,1148,1152,1157,1162,1167],{"type":32,"tag":63,"props":1136,"children":1137},{"style":70},[1138],{"type":37,"value":1139},"WHERE",{"type":32,"tag":63,"props":1141,"children":1142},{"style":106},[1143],{"type":37,"value":1052},{"type":32,"tag":63,"props":1145,"children":1146},{"style":76},[1147],{"type":37,"value":206},{"type":32,"tag":63,"props":1149,"children":1150},{"style":106},[1151],{"type":37,"value":333},{"type":32,"tag":63,"props":1153,"children":1154},{"style":70},[1155],{"type":37,"value":1156}," BETWEEN",{"type":32,"tag":63,"props":1158,"children":1159},{"style":145},[1160],{"type":37,"value":1161}," '2026-05-01'",{"type":32,"tag":63,"props":1163,"children":1164},{"style":70},[1165],{"type":37,"value":1166}," AND",{"type":32,"tag":63,"props":1168,"children":1169},{"style":145},[1170],{"type":37,"value":1171}," '2026-05-15'\n",{"type":32,"tag":63,"props":1173,"children":1174},{"class":65,"line":295},[1175,1179,1183,1187,1191],{"type":32,"tag":63,"props":1176,"children":1177},{"style":70},[1178],{"type":37,"value":491},{"type":32,"tag":63,"props":1180,"children":1181},{"style":106},[1182],{"type":37,"value":282},{"type":32,"tag":63,"props":1184,"children":1185},{"style":76},[1186],{"type":37,"value":287},{"type":32,"tag":63,"props":1188,"children":1189},{"style":106},[1190],{"type":37,"value":525},{"type":32,"tag":63,"props":1192,"children":1193},{"style":76},[1194],{"type":37,"value":530},{"type":32,"tag":33,"props":1196,"children":1197},{},[1198],{"type":37,"value":1199},"Questa query esegue il join verso la materialized view invece della tabella base — il numero di righe da scansionare scende da milioni a migliaia. Tuttavia continua a scansionare la tabella degli eventi ogni giorno. Nel passaggio successivo creiamo una tabella retention pre-aggregata.",{"type":32,"tag":40,"props":1201,"children":1203},{"id":1202},"tabella-retention-pre-aggregata-strato-finale",[1204],{"type":37,"value":1205},"Tabella Retention Pre-Aggregata: Strato Finale",{"type":32,"tag":33,"props":1207,"children":1208},{},[1209],{"type":37,"value":1210},"L'analisi cohort generalmente esamina intervalli fissi come \"Day 0, Day 1, Day 7, Day 30\" — non è necessario ricalcolare ogni giorno per ogni intervallo. Con dbt implementiamo questa logica:",{"type":32,"tag":1212,"props":1213,"children":1214},"ol",{},[1215,1227,1232],{"type":32,"tag":1216,"props":1217,"children":1218},"li",{},[1219,1221],{"type":37,"value":1220},"Ogni giorno, estrai i nuovi cohort dalla view ",{"type":32,"tag":59,"props":1222,"children":1224},{"className":1223},[],[1225],{"type":37,"value":1226},"user_cohorts",{"type":32,"tag":1216,"props":1228,"children":1229},{},[1230],{"type":37,"value":1231},"Calcola la retention degli ultimi 30 giorni per ogni cohort (dopo i primi 30 giorni non cambierà più)",{"type":32,"tag":1216,"props":1233,"children":1234},{},[1235,1237,1243,1245],{"type":37,"value":1236},"Scrivi il risultato nella tabella ",{"type":32,"tag":59,"props":1238,"children":1240},{"className":1239},[],[1241],{"type":37,"value":1242},"cohort_retention_summary",{"type":37,"value":1244}," in modo ",{"type":32,"tag":1246,"props":1247,"children":1248},"strong",{},[1249],{"type":37,"value":1250},"incrementale",{"type":32,"tag":33,"props":1252,"children":1253},{},[1254],{"type":37,"value":1255},"Modello dbt:",{"type":32,"tag":52,"props":1257,"children":1259},{"className":54,"code":1258,"language":56,"meta":16,"style":16},"{{\n  config(\n    materialized='incremental',\n    unique_key=['cohort_date','day_n'],\n    partition_by={'field':'cohort_date','data_type':'date'},\n    cluster_by=['day_n']\n  )\n}}\n\nWITH cohorts_to_update AS (\n  SELECT DISTINCT cohort_date \n  FROM {{ ref('user_cohorts') }}\n  WHERE cohort_date >= CURRENT_DATE() - 31\n  {% if is_incremental() %}\n    AND cohort_date > (SELECT MAX(cohort_date) FROM {{ this }})\n  {% endif %}\n),\nretention_calc AS (\n  SELECT \n    c.cohort_date,\n    DATE_DIFF(DATE(e.event_timestamp), c.cohort_date, DAY) AS day_n,\n    COUNT(DISTINCT e.user_id) AS retained_users,\n    MAX(c.first_day_events) AS cohort_size\n  FROM {{ ref('user_cohorts') }} c\n  JOIN {{ source('raw','events') }} e \n    ON c.user_id = e.user_id\n  WHERE c.cohort_date IN (SELECT cohort_date FROM cohorts_to_update)\n    AND DATE(e.event_timestamp) >= c.cohort_date\n    AND DATE_DIFF(DATE(e.event_timestamp), c.cohort_date, DAY) \u003C= 30\n  GROUP BY 1,2\n)\nSELECT \n  cohort_date,\n  day_n,\n  retained_users,\n  cohort_size,\n  SAFE_DIVIDE(retained_users, cohort_size) AS retention_rate\nFROM retention_calc;\n",[1260],{"type":32,"tag":59,"props":1261,"children":1262},{"__ignoreMap":16},[1263,1271,1279,1301,1318,1373,1390,1398,1406,1415,1435,1448,1470,1502,1520,1565,1573,1580,1596,1608,1629,1694,1736,1775,1796,1829,1867,1913,1961,2032,2052,2060,2072,2081,2090,2099,2108,2126],{"type":32,"tag":63,"props":1264,"children":1265},{"class":65,"line":66},[1266],{"type":32,"tag":63,"props":1267,"children":1268},{"style":76},[1269],{"type":37,"value":1270},"{{\n",{"type":32,"tag":63,"props":1272,"children":1273},{"class":65,"line":92},[1274],{"type":32,"tag":63,"props":1275,"children":1276},{"style":76},[1277],{"type":37,"value":1278},"  config(\n",{"type":32,"tag":63,"props":1280,"children":1281},{"class":65,"line":136},[1282,1287,1292,1297],{"type":32,"tag":63,"props":1283,"children":1284},{"style":76},[1285],{"type":37,"value":1286},"    materialized",{"type":32,"tag":63,"props":1288,"children":1289},{"style":70},[1290],{"type":37,"value":1291},"=",{"type":32,"tag":63,"props":1293,"children":1294},{"style":145},[1295],{"type":37,"value":1296},"'incremental'",{"type":32,"tag":63,"props":1298,"children":1299},{"style":76},[1300],{"type":37,"value":338},{"type":32,"tag":63,"props":1302,"children":1303},{"class":65,"line":151},[1304,1309,1313],{"type":32,"tag":63,"props":1305,"children":1306},{"style":76},[1307],{"type":37,"value":1308},"    unique_key",{"type":32,"tag":63,"props":1310,"children":1311},{"style":70},[1312],{"type":37,"value":1291},{"type":32,"tag":63,"props":1314,"children":1315},{"style":76},[1316],{"type":37,"value":1317},"['cohort_date','day_n'],\n",{"type":32,"tag":63,"props":1319,"children":1320},{"class":65,"line":165},[1321,1326,1330,1335,1340,1345,1350,1354,1359,1363,1368],{"type":32,"tag":63,"props":1322,"children":1323},{"style":76},[1324],{"type":37,"value":1325},"    partition_by",{"type":32,"tag":63,"props":1327,"children":1328},{"style":70},[1329],{"type":37,"value":1291},{"type":32,"tag":63,"props":1331,"children":1332},{"style":76},[1333],{"type":37,"value":1334},"{",{"type":32,"tag":63,"props":1336,"children":1337},{"style":145},[1338],{"type":37,"value":1339},"'field'",{"type":32,"tag":63,"props":1341,"children":1342},{"style":76},[1343],{"type":37,"value":1344},":",{"type":32,"tag":63,"props":1346,"children":1347},{"style":145},[1348],{"type":37,"value":1349},"'cohort_date'",{"type":32,"tag":63,"props":1351,"children":1352},{"style":76},[1353],{"type":37,"value":287},{"type":32,"tag":63,"props":1355,"children":1356},{"style":145},[1357],{"type":37,"value":1358},"'data_type'",{"type":32,"tag":63,"props":1360,"children":1361},{"style":76},[1362],{"type":37,"value":1344},{"type":32,"tag":63,"props":1364,"children":1365},{"style":145},[1366],{"type":37,"value":1367},"'date'",{"type":32,"tag":63,"props":1369,"children":1370},{"style":76},[1371],{"type":37,"value":1372},"},\n",{"type":32,"tag":63,"props":1374,"children":1375},{"class":65,"line":174},[1376,1381,1385],{"type":32,"tag":63,"props":1377,"children":1378},{"style":76},[1379],{"type":37,"value":1380},"    cluster_by",{"type":32,"tag":63,"props":1382,"children":1383},{"style":70},[1384],{"type":37,"value":1291},{"type":32,"tag":63,"props":1386,"children":1387},{"style":76},[1388],{"type":37,"value":1389},"['day_n']\n",{"type":32,"tag":63,"props":1391,"children":1392},{"class":65,"line":191},[1393],{"type":32,"tag":63,"props":1394,"children":1395},{"style":76},[1396],{"type":37,"value":1397},"  )\n",{"type":32,"tag":63,"props":1399,"children":1400},{"class":65,"line":26},[1401],{"type":32,"tag":63,"props":1402,"children":1403},{"style":76},[1404],{"type":37,"value":1405},"}}\n",{"type":32,"tag":63,"props":1407,"children":1408},{"class":65,"line":272},[1409],{"type":32,"tag":63,"props":1410,"children":1412},{"emptyLinePlaceholder":1411},true,[1413],{"type":37,"value":1414},"\n",{"type":32,"tag":63,"props":1416,"children":1417},{"class":65,"line":295},[1418,1422,1427,1431],{"type":32,"tag":63,"props":1419,"children":1420},{"style":70},[1421],{"type":37,"value":73},{"type":32,"tag":63,"props":1423,"children":1424},{"style":76},[1425],{"type":37,"value":1426}," cohorts_to_update ",{"type":32,"tag":63,"props":1428,"children":1429},{"style":70},[1430],{"type":37,"value":84},{"type":32,"tag":63,"props":1432,"children":1433},{"style":76},[1434],{"type":37,"value":89},{"type":32,"tag":63,"props":1436,"children":1437},{"class":65,"line":304},[1438,1443],{"type":32,"tag":63,"props":1439,"children":1440},{"style":70},[1441],{"type":37,"value":1442},"  SELECT DISTINCT",{"type":32,"tag":63,"props":1444,"children":1445},{"style":76},[1446],{"type":37,"value":1447}," cohort_date \n",{"type":32,"tag":63,"props":1449,"children":1450},{"class":65,"line":318},[1451,1455,1460,1465],{"type":32,"tag":63,"props":1452,"children":1453},{"style":70},[1454],{"type":37,"value":142},{"type":32,"tag":63,"props":1456,"children":1457},{"style":76},[1458],{"type":37,"value":1459}," {{ ref(",{"type":32,"tag":63,"props":1461,"children":1462},{"style":145},[1463],{"type":37,"value":1464},"'user_cohorts'",{"type":32,"tag":63,"props":1466,"children":1467},{"style":76},[1468],{"type":37,"value":1469},") }}\n",{"type":32,"tag":63,"props":1471,"children":1472},{"class":65,"line":341},[1473,1478,1483,1487,1492,1497],{"type":32,"tag":63,"props":1474,"children":1475},{"style":70},[1476],{"type":37,"value":1477},"  WHERE",{"type":32,"tag":63,"props":1479,"children":1480},{"style":76},[1481],{"type":37,"value":1482}," cohort_date ",{"type":32,"tag":63,"props":1484,"children":1485},{"style":70},[1486],{"type":37,"value":1118},{"type":32,"tag":63,"props":1488,"children":1489},{"style":76},[1490],{"type":37,"value":1491}," CURRENT_DATE() ",{"type":32,"tag":63,"props":1493,"children":1494},{"style":70},[1495],{"type":37,"value":1496},"-",{"type":32,"tag":63,"props":1498,"children":1499},{"style":106},[1500],{"type":37,"value":1501}," 31\n",{"type":32,"tag":63,"props":1503,"children":1504},{"class":65,"line":403},[1505,1510,1515],{"type":32,"tag":63,"props":1506,"children":1507},{"style":76},[1508],{"type":37,"value":1509},"  {% ",{"type":32,"tag":63,"props":1511,"children":1512},{"style":70},[1513],{"type":37,"value":1514},"if",{"type":32,"tag":63,"props":1516,"children":1517},{"style":76},[1518],{"type":37,"value":1519}," is_incremental() %}\n",{"type":32,"tag":63,"props":1521,"children":1522},{"class":65,"line":447},[1523,1528,1532,1537,1542,1546,1551,1556,1560],{"type":32,"tag":63,"props":1524,"children":1525},{"style":70},[1526],{"type":37,"value":1527},"    AND",{"type":32,"tag":63,"props":1529,"children":1530},{"style":76},[1531],{"type":37,"value":1482},{"type":32,"tag":63,"props":1533,"children":1534},{"style":70},[1535],{"type":37,"value":1536},">",{"type":32,"tag":63,"props":1538,"children":1539},{"style":76},[1540],{"type":37,"value":1541}," (",{"type":32,"tag":63,"props":1543,"children":1544},{"style":70},[1545],{"type":37,"value":310},{"type":32,"tag":63,"props":1547,"children":1548},{"style":106},[1549],{"type":37,"value":1550}," MAX",{"type":32,"tag":63,"props":1552,"children":1553},{"style":76},[1554],{"type":37,"value":1555},"(cohort_date) ",{"type":32,"tag":63,"props":1557,"children":1558},{"style":70},[1559],{"type":37,"value":453},{"type":32,"tag":63,"props":1561,"children":1562},{"style":76},[1563],{"type":37,"value":1564}," {{ this }})\n",{"type":32,"tag":63,"props":1566,"children":1567},{"class":65,"line":461},[1568],{"type":32,"tag":63,"props":1569,"children":1570},{"style":76},[1571],{"type":37,"value":1572},"  {% endif %}\n",{"type":32,"tag":63,"props":1574,"children":1575},{"class":65,"line":485},[1576],{"type":32,"tag":63,"props":1577,"children":1578},{"style":76},[1579],{"type":37,"value":171},{"type":32,"tag":63,"props":1581,"children":1582},{"class":65,"line":506},[1583,1588,1592],{"type":32,"tag":63,"props":1584,"children":1585},{"style":76},[1586],{"type":37,"value":1587},"retention_calc ",{"type":32,"tag":63,"props":1589,"children":1590},{"style":70},[1591],{"type":37,"value":84},{"type":32,"tag":63,"props":1593,"children":1594},{"style":76},[1595],{"type":37,"value":89},{"type":32,"tag":63,"props":1597,"children":1599},{"class":65,"line":1598},19,[1600,1604],{"type":32,"tag":63,"props":1601,"children":1602},{"style":70},[1603],{"type":37,"value":98},{"type":32,"tag":63,"props":1605,"children":1606},{"style":76},[1607],{"type":37,"value":315},{"type":32,"tag":63,"props":1609,"children":1611},{"class":65,"line":1610},20,[1612,1617,1621,1625],{"type":32,"tag":63,"props":1613,"children":1614},{"style":106},[1615],{"type":37,"value":1616},"    c",{"type":32,"tag":63,"props":1618,"children":1619},{"style":76},[1620],{"type":37,"value":206},{"type":32,"tag":63,"props":1622,"children":1623},{"style":106},[1624],{"type":37,"value":333},{"type":32,"tag":63,"props":1626,"children":1627},{"style":76},[1628],{"type":37,"value":338},{"type":32,"tag":63,"props":1630,"children":1632},{"class":65,"line":1631},21,[1633,1638,1642,1646,1650,1654,1658,1662,1666,1670,1674,1678,1682,1686,1690],{"type":32,"tag":63,"props":1634,"children":1635},{"style":76},[1636],{"type":37,"value":1637},"    DATE_DIFF(",{"type":32,"tag":63,"props":1639,"children":1640},{"style":70},[1641],{"type":37,"value":119},{"type":32,"tag":63,"props":1643,"children":1644},{"style":76},[1645],{"type":37,"value":114},{"type":32,"tag":63,"props":1647,"children":1648},{"style":106},[1649],{"type":37,"value":229},{"type":32,"tag":63,"props":1651,"children":1652},{"style":76},[1653],{"type":37,"value":206},{"type":32,"tag":63,"props":1655,"children":1656},{"style":106},[1657],{"type":37,"value":238},{"type":32,"tag":63,"props":1659,"children":1660},{"style":76},[1661],{"type":37,"value":934},{"type":32,"tag":63,"props":1663,"children":1664},{"style":106},[1665],{"type":37,"value":939},{"type":32,"tag":63,"props":1667,"children":1668},{"style":76},[1669],{"type":37,"value":206},{"type":32,"tag":63,"props":1671,"children":1672},{"style":106},[1673],{"type":37,"value":333},{"type":32,"tag":63,"props":1675,"children":1676},{"style":76},[1677],{"type":37,"value":216},{"type":32,"tag":63,"props":1679,"children":1680},{"style":70},[1681],{"type":37,"value":387},{"type":32,"tag":63,"props":1683,"children":1684},{"style":76},[1685],{"type":37,"value":243},{"type":32,"tag":63,"props":1687,"children":1688},{"style":70},[1689],{"type":37,"value":84},{"type":32,"tag":63,"props":1691,"children":1692},{"style":76},[1693],{"type":37,"value":400},{"type":32,"tag":63,"props":1695,"children":1697},{"class":65,"line":1696},22,[1698,1703,1707,1711,1715,1719,1723,1727,1731],{"type":32,"tag":63,"props":1699,"children":1700},{"style":106},[1701],{"type":37,"value":1702},"    COUNT",{"type":32,"tag":63,"props":1704,"children":1705},{"style":76},[1706],{"type":37,"value":114},{"type":32,"tag":63,"props":1708,"children":1709},{"style":70},[1710],{"type":37,"value":418},{"type":32,"tag":63,"props":1712,"children":1713},{"style":106},[1714],{"type":37,"value":201},{"type":32,"tag":63,"props":1716,"children":1717},{"style":76},[1718],{"type":37,"value":206},{"type":32,"tag":63,"props":1720,"children":1721},{"style":106},[1722],{"type":37,"value":211},{"type":32,"tag":63,"props":1724,"children":1725},{"style":76},[1726],{"type":37,"value":243},{"type":32,"tag":63,"props":1728,"children":1729},{"style":70},[1730],{"type":37,"value":84},{"type":32,"tag":63,"props":1732,"children":1733},{"style":76},[1734],{"type":37,"value":1735}," retained_users,\n",{"type":32,"tag":63,"props":1737,"children":1739},{"class":65,"line":1738},23,[1740,1745,1749,1753,1757,1762,1766,1770],{"type":32,"tag":63,"props":1741,"children":1742},{"style":106},[1743],{"type":37,"value":1744},"    MAX",{"type":32,"tag":63,"props":1746,"children":1747},{"style":76},[1748],{"type":37,"value":114},{"type":32,"tag":63,"props":1750,"children":1751},{"style":106},[1752],{"type":37,"value":939},{"type":32,"tag":63,"props":1754,"children":1755},{"style":76},[1756],{"type":37,"value":206},{"type":32,"tag":63,"props":1758,"children":1759},{"style":106},[1760],{"type":37,"value":1761},"first_day_events",{"type":32,"tag":63,"props":1763,"children":1764},{"style":76},[1765],{"type":37,"value":243},{"type":32,"tag":63,"props":1767,"children":1768},{"style":70},[1769],{"type":37,"value":84},{"type":32,"tag":63,"props":1771,"children":1772},{"style":76},[1773],{"type":37,"value":1774}," cohort_size\n",{"type":32,"tag":63,"props":1776,"children":1778},{"class":65,"line":1777},24,[1779,1783,1787,1791],{"type":32,"tag":63,"props":1780,"children":1781},{"style":70},[1782],{"type":37,"value":142},{"type":32,"tag":63,"props":1784,"children":1785},{"style":76},[1786],{"type":37,"value":1459},{"type":32,"tag":63,"props":1788,"children":1789},{"style":145},[1790],{"type":37,"value":1464},{"type":32,"tag":63,"props":1792,"children":1793},{"style":76},[1794],{"type":37,"value":1795},") }} c\n",{"type":32,"tag":63,"props":1797,"children":1799},{"class":65,"line":1798},25,[1800,1805,1810,1815,1819,1824],{"type":32,"tag":63,"props":1801,"children":1802},{"style":70},[1803],{"type":37,"value":1804},"  JOIN",{"type":32,"tag":63,"props":1806,"children":1807},{"style":76},[1808],{"type":37,"value":1809}," {{ source(",{"type":32,"tag":63,"props":1811,"children":1812},{"style":145},[1813],{"type":37,"value":1814},"'raw'",{"type":32,"tag":63,"props":1816,"children":1817},{"style":76},[1818],{"type":37,"value":287},{"type":32,"tag":63,"props":1820,"children":1821},{"style":145},[1822],{"type":37,"value":1823},"'events'",{"type":32,"tag":63,"props":1825,"children":1826},{"style":76},[1827],{"type":37,"value":1828},") }} e \n",{"type":32,"tag":63,"props":1830,"children":1832},{"class":65,"line":1831},26,[1833,1838,1842,1846,1850,1854,1858,1862],{"type":32,"tag":63,"props":1834,"children":1835},{"style":70},[1836],{"type":37,"value":1837},"    ON",{"type":32,"tag":63,"props":1839,"children":1840},{"style":106},[1841],{"type":37,"value":1052},{"type":32,"tag":63,"props":1843,"children":1844},{"style":76},[1845],{"type":37,"value":206},{"type":32,"tag":63,"props":1847,"children":1848},{"style":106},[1849],{"type":37,"value":211},{"type":32,"tag":63,"props":1851,"children":1852},{"style":70},[1853],{"type":37,"value":1065},{"type":32,"tag":63,"props":1855,"children":1856},{"style":106},[1857],{"type":37,"value":201},{"type":32,"tag":63,"props":1859,"children":1860},{"style":76},[1861],{"type":37,"value":206},{"type":32,"tag":63,"props":1863,"children":1864},{"style":106},[1865],{"type":37,"value":1866},"user_id\n",{"type":32,"tag":63,"props":1868,"children":1870},{"class":65,"line":1869},27,[1871,1875,1879,1883,1887,1892,1896,1900,1904,1908],{"type":32,"tag":63,"props":1872,"children":1873},{"style":70},[1874],{"type":37,"value":1477},{"type":32,"tag":63,"props":1876,"children":1877},{"style":106},[1878],{"type":37,"value":1052},{"type":32,"tag":63,"props":1880,"children":1881},{"style":76},[1882],{"type":37,"value":206},{"type":32,"tag":63,"props":1884,"children":1885},{"style":106},[1886],{"type":37,"value":333},{"type":32,"tag":63,"props":1888,"children":1889},{"style":70},[1890],{"type":37,"value":1891}," IN",{"type":32,"tag":63,"props":1893,"children":1894},{"style":76},[1895],{"type":37,"value":1541},{"type":32,"tag":63,"props":1897,"children":1898},{"style":70},[1899],{"type":37,"value":310},{"type":32,"tag":63,"props":1901,"children":1902},{"style":76},[1903],{"type":37,"value":1482},{"type":32,"tag":63,"props":1905,"children":1906},{"style":70},[1907],{"type":37,"value":453},{"type":32,"tag":63,"props":1909,"children":1910},{"style":76},[1911],{"type":37,"value":1912}," cohorts_to_update)\n",{"type":32,"tag":63,"props":1914,"children":1916},{"class":65,"line":1915},28,[1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957],{"type":32,"tag":63,"props":1918,"children":1919},{"style":70},[1920],{"type":37,"value":1527},{"type":32,"tag":63,"props":1922,"children":1923},{"style":70},[1924],{"type":37,"value":619},{"type":32,"tag":63,"props":1926,"children":1927},{"style":76},[1928],{"type":37,"value":114},{"type":32,"tag":63,"props":1930,"children":1931},{"style":106},[1932],{"type":37,"value":229},{"type":32,"tag":63,"props":1934,"children":1935},{"style":76},[1936],{"type":37,"value":206},{"type":32,"tag":63,"props":1938,"children":1939},{"style":106},[1940],{"type":37,"value":238},{"type":32,"tag":63,"props":1942,"children":1943},{"style":76},[1944],{"type":37,"value":243},{"type":32,"tag":63,"props":1946,"children":1947},{"style":70},[1948],{"type":37,"value":1118},{"type":32,"tag":63,"props":1950,"children":1951},{"style":106},[1952],{"type":37,"value":1052},{"type":32,"tag":63,"props":1954,"children":1955},{"style":76},[1956],{"type":37,"value":206},{"type":32,"tag":63,"props":1958,"children":1959},{"style":106},[1960],{"type":37,"value":1131},{"type":32,"tag":63,"props":1962,"children":1964},{"class":65,"line":1963},29,[1965,1969,1974,1978,1982,1986,1990,1994,1998,2002,2006,2010,2014,2018,2022,2027],{"type":32,"tag":63,"props":1966,"children":1967},{"style":70},[1968],{"type":37,"value":1527},{"type":32,"tag":63,"props":1970,"children":1971},{"style":76},[1972],{"type":37,"value":1973}," DATE_DIFF(",{"type":32,"tag":63,"props":1975,"children":1976},{"style":70},[1977],{"type":37,"value":119},{"type":32,"tag":63,"props":1979,"children":1980},{"style":76},[1981],{"type":37,"value":114},{"type":32,"tag":63,"props":1983,"children":1984},{"style":106},[1985],{"type":37,"value":229},{"type":32,"tag":63,"props":1987,"children":1988},{"style":76},[1989],{"type":37,"value":206},{"type":32,"tag":63,"props":1991,"children":1992},{"style":106},[1993],{"type":37,"value":238},{"type":32,"tag":63,"props":1995,"children":1996},{"style":76},[1997],{"type":37,"value":934},{"type":32,"tag":63,"props":1999,"children":2000},{"style":106},[2001],{"type":37,"value":939},{"type":32,"tag":63,"props":2003,"children":2004},{"style":76},[2005],{"type":37,"value":206},{"type":32,"tag":63,"props":2007,"children":2008},{"style":106},[2009],{"type":37,"value":333},{"type":32,"tag":63,"props":2011,"children":2012},{"style":76},[2013],{"type":37,"value":216},{"type":32,"tag":63,"props":2015,"children":2016},{"style":70},[2017],{"type":37,"value":387},{"type":32,"tag":63,"props":2019,"children":2020},{"style":76},[2021],{"type":37,"value":243},{"type":32,"tag":63,"props":2023,"children":2024},{"style":70},[2025],{"type":37,"value":2026},"\u003C=",{"type":32,"tag":63,"props":2028,"children":2029},{"style":106},[2030],{"type":37,"value":2031}," 30\n",{"type":32,"tag":63,"props":2033,"children":2035},{"class":65,"line":2034},30,[2036,2040,2044,2048],{"type":32,"tag":63,"props":2037,"children":2038},{"style":70},[2039],{"type":37,"value":157},{"type":32,"tag":63,"props":2041,"children":2042},{"style":106},[2043],{"type":37,"value":282},{"type":32,"tag":63,"props":2045,"children":2046},{"style":76},[2047],{"type":37,"value":287},{"type":32,"tag":63,"props":2049,"children":2050},{"style":106},[2051],{"type":37,"value":292},{"type":32,"tag":63,"props":2053,"children":2055},{"class":65,"line":2054},31,[2056],{"type":32,"tag":63,"props":2057,"children":2058},{"style":76},[2059],{"type":37,"value":301},{"type":32,"tag":63,"props":2061,"children":2063},{"class":65,"line":2062},32,[2064,2068],{"type":32,"tag":63,"props":2065,"children":2066},{"style":70},[2067],{"type":37,"value":310},{"type":32,"tag":63,"props":2069,"children":2070},{"style":76},[2071],{"type":37,"value":315},{"type":32,"tag":63,"props":2073,"children":2075},{"class":65,"line":2074},33,[2076],{"type":32,"tag":63,"props":2077,"children":2078},{"style":76},[2079],{"type":37,"value":2080},"  cohort_date,\n",{"type":32,"tag":63,"props":2082,"children":2084},{"class":65,"line":2083},34,[2085],{"type":32,"tag":63,"props":2086,"children":2087},{"style":76},[2088],{"type":37,"value":2089},"  day_n,\n",{"type":32,"tag":63,"props":2091,"children":2093},{"class":65,"line":2092},35,[2094],{"type":32,"tag":63,"props":2095,"children":2096},{"style":76},[2097],{"type":37,"value":2098},"  retained_users,\n",{"type":32,"tag":63,"props":2100,"children":2102},{"class":65,"line":2101},36,[2103],{"type":32,"tag":63,"props":2104,"children":2105},{"style":76},[2106],{"type":37,"value":2107},"  cohort_size,\n",{"type":32,"tag":63,"props":2109,"children":2111},{"class":65,"line":2110},37,[2112,2117,2121],{"type":32,"tag":63,"props":2113,"children":2114},{"style":76},[2115],{"type":37,"value":2116},"  SAFE_DIVIDE(retained_users, cohort_size) ",{"type":32,"tag":63,"props":2118,"children":2119},{"style":70},[2120],{"type":37,"value":84},{"type":32,"tag":63,"props":2122,"children":2123},{"style":76},[2124],{"type":37,"value":2125}," retention_rate\n",{"type":32,"tag":63,"props":2127,"children":2129},{"class":65,"line":2128},38,[2130,2134],{"type":32,"tag":63,"props":2131,"children":2132},{"style":70},[2133],{"type":37,"value":453},{"type":32,"tag":63,"props":2135,"children":2136},{"style":76},[2137],{"type":37,"value":2138}," retention_calc;\n",{"type":32,"tag":33,"props":2140,"children":2141},{},[2142,2144,2153],{"type":37,"value":2143},"Questo modello aggiorna ogni giorno solo i cohort degli ultimi 31 giorni. I cohort più vecchi di 31 giorni hanno una retention stabile — non vengono ricalcolati. L'utilizzo di slot scende del 95%. ",{"type":32,"tag":2145,"props":2146,"children":2150},"a",{"href":2147,"rel":2148},"https:\u002F\u002Fwww.roibase.com.tr\u002Fit\u002Fretention-engineering-cdp",[2149],"nofollow",[2151],{"type":37,"value":2152},"Nel processo di CDP & Retention Engineering",{"type":37,"value":2154}," questa tabella viene collegata direttamente al dashboard — gli strumenti BI (Looker, Metabase) restituiscono query in 100ms.",{"type":32,"tag":40,"props":2156,"children":2158},{"id":2157},"strategia-di-query-cost-e-partition-expiration",[2159],{"type":37,"value":2160},"Strategia di Query Cost e Partition Expiration",{"type":32,"tag":33,"props":2162,"children":2163},{},[2164],{"type":37,"value":2165},"Su BigQuery lo storage è economico ($0,02\u002FGB\u002Fmese), il compute è costoso ($5\u002FTB di dati elaborati). Poiché l'analisi di retention è retrospettiva, le partition più vecchie vengono scansionate frequentemente. Due ottimizzazioni:",{"type":32,"tag":1212,"props":2167,"children":2168},{},[2169,2186],{"type":32,"tag":1216,"props":2170,"children":2171},{},[2172,2177,2179,2184],{"type":32,"tag":1246,"props":2173,"children":2174},{},[2175],{"type":37,"value":2176},"Partition expiration:",{"type":37,"value":2178}," Cancella automaticamente le partition della tabella ",{"type":32,"tag":59,"props":2180,"children":2182},{"className":2181},[],[2183],{"type":37,"value":541},{"type":37,"value":2185}," più vecchie di 90 giorni — dopo che il calcolo cohort è completato, non hai più bisogno degli eventi raw.",{"type":32,"tag":1216,"props":2187,"children":2188},{},[2189,2194,2196,2202],{"type":32,"tag":1246,"props":2190,"children":2191},{},[2192],{"type":37,"value":2193},"Aggiorna le statistiche di clustering periodicamente:",{"type":37,"value":2195}," ",{"type":32,"tag":59,"props":2197,"children":2199},{"className":2198},[],[2200],{"type":37,"value":2201},"ANALYZE TABLE ... UPDATE STATISTICS",{"type":37,"value":2203}," — l'optimizer di query sceglie un piano di esecuzione migliore.",{"type":32,"tag":33,"props":2205,"children":2206},{},[2207],{"type":37,"value":2208},"Esempio di confronto dei costi (100M eventi\u002Fgiorno, 1M utenti):",{"type":32,"tag":2210,"props":2211,"children":2212},"table",{},[2213,2237],{"type":32,"tag":2214,"props":2215,"children":2216},"thead",{},[2217],{"type":32,"tag":2218,"props":2219,"children":2220},"tr",{},[2221,2227,2232],{"type":32,"tag":2222,"props":2223,"children":2224},"th",{},[2225],{"type":37,"value":2226},"Metodo",{"type":32,"tag":2222,"props":2228,"children":2229},{},[2230],{"type":37,"value":2231},"Dati elaborati\u002Fgiorno",{"type":32,"tag":2222,"props":2233,"children":2234},{},[2235],{"type":37,"value":2236},"Costo compute mensile",{"type":32,"tag":2238,"props":2239,"children":2240},"tbody",{},[2241,2260,2278],{"type":32,"tag":2218,"props":2242,"children":2243},{},[2244,2250,2255],{"type":32,"tag":2245,"props":2246,"children":2247},"td",{},[2248],{"type":37,"value":2249},"Query ingenua (full scan)",{"type":32,"tag":2245,"props":2251,"children":2252},{},[2253],{"type":37,"value":2254},"12TB",{"type":32,"tag":2245,"props":2256,"children":2257},{},[2258],{"type":37,"value":2259},"$600",{"type":32,"tag":2218,"props":2261,"children":2262},{},[2263,2268,2273],{"type":32,"tag":2245,"props":2264,"children":2265},{},[2266],{"type":37,"value":2267},"Partitioned + materialized view",{"type":32,"tag":2245,"props":2269,"children":2270},{},[2271],{"type":37,"value":2272},"800GB",{"type":32,"tag":2245,"props":2274,"children":2275},{},[2276],{"type":37,"value":2277},"$40",{"type":32,"tag":2218,"props":2279,"children":2280},{},[2281,2286,2291],{"type":32,"tag":2245,"props":2282,"children":2283},{},[2284],{"type":37,"value":2285},"Tabella pre-aggregata (incrementale)",{"type":32,"tag":2245,"props":2287,"children":2288},{},[2289],{"type":37,"value":2290},"50GB",{"type":32,"tag":2245,"props":2292,"children":2293},{},[2294],{"type":37,"value":2295},"$2,50",{"type":32,"tag":33,"props":2297,"children":2298},{},[2299],{"type":37,"value":2300},"Aggiungere lo strato pre-aggregato riduce il costo di compute di 240 volte. Questa differenza è critica in produzione — soprattutto se l'analisi di retention viene aggiornata ogni ora.",{"type":32,"tag":40,"props":2302,"children":2304},{"id":2303},"trade-off-della-retention-analysis-in-tempo-reale",[2305],{"type":37,"value":2306},"Trade-off della Retention Analysis in Tempo Reale",{"type":32,"tag":33,"props":2308,"children":2309},{},[2310],{"type":37,"value":2311},"La struttura con materialized view e pre-aggregate introduce un trade-off di latenza: i dati ritardano di 1-5 minuti. Se hai bisogno di retention analysis in tempo reale (ad esempio per le prime 24 ore), puoi implementare un approccio ibrido:",{"type":32,"tag":2313,"props":2314,"children":2315},"ul",{},[2316,2321],{"type":32,"tag":1216,"props":2317,"children":2318},{},[2319],{"type":37,"value":2320},"Per i dati delle ultime 24 ore: streaming insert + real-time query (cache disabilitato)",{"type":32,"tag":1216,"props":2322,"children":2323},{},[2324],{"type":37,"value":2325},"Per i dati più vecchi di 24 ore: tabella pre-aggregata",{"type":32,"tag":33,"props":2327,"children":2328},{},[2329],{"type":37,"value":2330},"In questo caso la query BI unisce le due fonti con UNION ALL:",{"type":32,"tag":52,"props":2332,"children":2334},{"className":54,"code":2333,"language":56,"meta":16,"style":16},"SELECT * FROM cohort_retention_summary WHERE cohort_date \u003C CURRENT_DATE()\nUNION ALL\nSELECT * FROM realtime_cohort_view WHERE cohort_date = CURRENT_DATE();\n",[2335],{"type":32,"tag":59,"props":2336,"children":2337},{"__ignoreMap":16},[2338,2376,2384],{"type":32,"tag":63,"props":2339,"children":2340},{"class":65,"line":66},[2341,2345,2349,2353,2358,2362,2366,2371],{"type":32,"tag":63,"props":2342,"children":2343},{"style":70},[2344],{"type":37,"value":310},{"type":32,"tag":63,"props":2346,"children":2347},{"style":70},[2348],{"type":37,"value":659},{"type":32,"tag":63,"props":2350,"children":2351},{"style":70},[2352],{"type":37,"value":664},{"type":32,"tag":63,"props":2354,"children":2355},{"style":76},[2356],{"type":37,"value":2357}," cohort_retention_summary ",{"type":32,"tag":63,"props":2359,"children":2360},{"style":70},[2361],{"type":37,"value":1139},{"type":32,"tag":63,"props":2363,"children":2364},{"style":76},[2365],{"type":37,"value":1482},{"type":32,"tag":63,"props":2367,"children":2368},{"style":70},[2369],{"type":37,"value":2370},"\u003C",{"type":32,"tag":63,"props":2372,"children":2373},{"style":76},[2374],{"type":37,"value":2375}," CURRENT_DATE()\n",{"type":32,"tag":63,"props":2377,"children":2378},{"class":65,"line":92},[2379],{"type":32,"tag":63,"props":2380,"children":2381},{"style":70},[2382],{"type":37,"value":2383},"UNION ALL\n",{"type":32,"tag":63,"props":2385,"children":2386},{"class":65,"line":136},[2387,2391,2395,2399,2404,2408,2412,2416],{"type":32,"tag":63,"props":2388,"children":2389},{"style":70},[2390],{"type":37,"value":310},{"type":32,"tag":63,"props":2392,"children":2393},{"style":70},[2394],{"type":37,"value":659},{"type":32,"tag":63,"props":2396,"children":2397},{"style":70},[2398],{"type":37,"value":664},{"type":32,"tag":63,"props":2400,"children":2401},{"style":76},[2402],{"type":37,"value":2403}," realtime_cohort_view ",{"type":32,"tag":63,"props":2405,"children":2406},{"style":70},[2407],{"type":37,"value":1139},{"type":32,"tag":63,"props":2409,"children":2410},{"style":76},[2411],{"type":37,"value":1482},{"type":32,"tag":63,"props":2413,"children":2414},{"style":70},[2415],{"type":37,"value":1291},{"type":32,"tag":63,"props":2417,"children":2418},{"style":76},[2419],{"type":37,"value":2420}," CURRENT_DATE();\n",{"type":32,"tag":33,"props":2422,"children":2423},{},[2424],{"type":37,"value":2425},"Anche se la real-time view è costosa, poiché viene eseguita solo per il cohort più recente, l'impatto complessivo sul compute rimane contenuto.",{"type":32,"tag":40,"props":2427,"children":2429},{"id":2428},"segmentazione-cohort-e-esplosione-di-cardinalità",[2430],{"type":37,"value":2431},"Segmentazione Cohort e Esplosione di Cardinalità",{"type":32,"tag":33,"props":2433,"children":2434},{},[2435],{"type":37,"value":2436},"Disaggregare l'analisi di retention per segmento utente (piattaforma, paese, canale di acquisizione) può innescare problemi di cardinalità. Ad esempio 5 segmenti × 30 giorni × 365 cohort = 54.750 righe univoche. In questo caso:",{"type":32,"tag":1212,"props":2438,"children":2439},{},[2440,2450,2460],{"type":32,"tag":1216,"props":2441,"children":2442},{},[2443,2448],{"type":32,"tag":1246,"props":2444,"children":2445},{},[2446],{"type":37,"value":2447},"Limita il numero di segmenti:",{"type":37,"value":2449}," Esegui l'analisi su 3-5 segmenti più importanti, crea tabelle separate per gli altri.",{"type":32,"tag":1216,"props":2451,"children":2452},{},[2453,2458],{"type":32,"tag":1246,"props":2454,"children":2455},{},[2456],{"type":37,"value":2457},"Segmentazione dinamica:",{"type":37,"value":2459}," Anziché aggiungere informazioni di segmento alla tabella pre-aggregata, usa il filtering al momento del join — mantiene la flessibilità della query ma aumenta l'utilizzo di slot.",{"type":32,"tag":1216,"props":2461,"children":2462},{},[2463,2468],{"type":32,"tag":1246,"props":2464,"children":2465},{},[2466],{"type":37,"value":2467},"Tabella di rollup:",{"type":37,"value":2469}," Crea una tabella separata per cohort settimanali (weekly_cohort_retention) — la cardinalità scende dell'85%.",{"type":32,"tag":33,"props":2471,"children":2472},{},[2473,2475,2482],{"type":37,"value":2474},"Nel processo di ",{"type":32,"tag":2145,"props":2476,"children":2479},{"href":2477,"rel":2478},"https:\u002F\u002Fwww.roibase.com.tr\u002Fit\u002Fverianalizi",[2149],[2480],{"type":37,"value":2481},"Veri Analizi & İçgörü Mühendisliği",{"type":37,"value":2483}," di Roibase, integriamo la strategia di segmentazione con l'attribution della fonte di acquisizione — l'analisi cohort viene collegata direttamente alla performance del canale.",{"type":32,"tag":40,"props":2485,"children":2487},{"id":2486},"monitoraggio-e-rilevamento-di-regressioni",[2488],{"type":37,"value":2489},"Monitoraggio e Rilevamento di Regressioni",{"type":32,"tag":33,"props":2491,"children":2492},{},[2493],{"type":37,"value":2494},"Per monitorare la retention pipeline in produzione, traccia queste metriche:",{"type":32,"tag":2313,"props":2496,"children":2497},{},[2498,2508,2518],{"type":32,"tag":1216,"props":2499,"children":2500},{},[2501,2506],{"type":32,"tag":1246,"props":2502,"children":2503},{},[2504],{"type":37,"value":2505},"Query slot time:",{"type":37,"value":2507}," Utilizzo di slot BigQuery del refresh giornaliero — un aumento improvviso indica esplosione di cardinalità o perdita di partition pruning.",{"type":32,"tag":1216,"props":2509,"children":2510},{},[2511,2516],{"type":32,"tag":1246,"props":2512,"children":2513},{},[2514],{"type":37,"value":2515},"Row count delta:",{"type":37,"value":2517}," Numero di righe aggiunte ad ogni refresh — se superiore al previsto, segnala rischio di eventi duplicati.",{"type":32,"tag":1216,"props":2519,"children":2520},{},[2521,2526],{"type":32,"tag":1246,"props":2522,"children":2523},{},[2524],{"type":37,"value":2525},"Retention rate stddev:",{"type":37,"value":2527}," Una variazione improvvisa di Day 1 retention del 10%+ è un segnale di problemi di data quality.",{"type":32,"tag":33,"props":2529,"children":2530},{},[2531],{"type":37,"value":2532},"Puoi aggiungere questi check come test all'interno di dbt:",{"type":32,"tag":52,"props":2534,"children":2538},{"className":2535,"code":2536,"language":2537,"meta":16,"style":16},"language-yaml shiki shiki-themes github-dark","tests:\n  - dbt_utils.expression_is_true:\n      expression: \"retention_rate BETWEEN 0 AND 1\"\n  - dbt_utils.recency:\n      datepart: day\n      field: cohort_date\n      interval: 1\n","yaml",[2539],{"type":32,"tag":59,"props":2540,"children":2541},{"__ignoreMap":16},[2542,2556,2573,2591,2607,2624,2640],{"type":32,"tag":63,"props":2543,"children":2544},{"class":65,"line":66},[2545,2551],{"type":32,"tag":63,"props":2546,"children":2548},{"style":2547},"--shiki-default:#85E89D",[2549],{"type":37,"value":2550},"tests",{"type":32,"tag":63,"props":2552,"children":2553},{"style":76},[2554],{"type":37,"value":2555},":\n",{"type":32,"tag":63,"props":2557,"children":2558},{"class":65,"line":92},[2559,2564,2569],{"type":32,"tag":63,"props":2560,"children":2561},{"style":76},[2562],{"type":37,"value":2563},"  - ",{"type":32,"tag":63,"props":2565,"children":2566},{"style":2547},[2567],{"type":37,"value":2568},"dbt_utils.expression_is_true",{"type":32,"tag":63,"props":2570,"children":2571},{"style":76},[2572],{"type":37,"value":2555},{"type":32,"tag":63,"props":2574,"children":2575},{"class":65,"line":136},[2576,2581,2586],{"type":32,"tag":63,"props":2577,"children":2578},{"style":2547},[2579],{"type":37,"value":2580},"      expression",{"type":32,"tag":63,"props":2582,"children":2583},{"style":76},[2584],{"type":37,"value":2585},": ",{"type":32,"tag":63,"props":2587,"children":2588},{"style":145},[2589],{"type":37,"value":2590},"\"retention_rate BETWEEN 0 AND 1\"\n",{"type":32,"tag":63,"props":2592,"children":2593},{"class":65,"line":151},[2594,2598,2603],{"type":32,"tag":63,"props":2595,"children":2596},{"style":76},[2597],{"type":37,"value":2563},{"type":32,"tag":63,"props":2599,"children":2600},{"style":2547},[2601],{"type":37,"value":2602},"dbt_utils.recency",{"type":32,"tag":63,"props":2604,"children":2605},{"style":76},[2606],{"type":37,"value":2555},{"type":32,"tag":63,"props":2608,"children":2609},{"class":65,"line":165},[2610,2615,2619],{"type":32,"tag":63,"props":2611,"children":2612},{"style":2547},[2613],{"type":37,"value":2614},"      datepart",{"type":32,"tag":63,"props":2616,"children":2617},{"style":76},[2618],{"type":37,"value":2585},{"type":32,"tag":63,"props":2620,"children":2621},{"style":145},[2622],{"type":37,"value":2623},"day\n",{"type":32,"tag":63,"props":2625,"children":2626},{"class":65,"line":174},[2627,2632,2636],{"type":32,"tag":63,"props":2628,"children":2629},{"style":2547},[2630],{"type":37,"value":2631},"      field",{"type":32,"tag":63,"props":2633,"children":2634},{"style":76},[2635],{"type":37,"value":2585},{"type":32,"tag":63,"props":2637,"children":2638},{"style":145},[2639],{"type":37,"value":1131},{"type":32,"tag":63,"props":2641,"children":2642},{"class":65,"line":191},[2643,2648,2652],{"type":32,"tag":63,"props":2644,"children":2645},{"style":2547},[2646],{"type":37,"value":2647},"      interval",{"type":32,"tag":63,"props":2649,"children":2650},{"style":76},[2651],{"type":37,"value":2585},{"type":32,"tag":63,"props":2653,"children":2654},{"style":106},[2655],{"type":37,"value":2656},"1\n",{"type":32,"tag":33,"props":2658,"children":2659},{},[2660],{"type":37,"value":2661},"Se un test fallisce viene attivato un alert su Slack o PagerDuty — non è necessario controllare manualmente.",{"type":32,"tag":33,"props":2663,"children":2664},{},[2665],{"type":37,"value":2666},"L'architettura della tabella cohort trasforma l'analisi di retention da \"query ad-hoc\" a \"data product pronto per la produzione\". Il refresh incrementale con materialized view, il pruning delle query con partitioning, l'ottimizzazione degli slot con pre-aggregazione — ogni strato riduce i costi di 10 volte. Eseguire analisi di retention su milioni di utenti e miliardi di eventi ora si riduce a una query dashboard di 100ms. Decidere quali pattern di retention monitorare rimane compito tuo — ma elaborare i dati a questa velocità non è più un problema di engineering.",{"type":32,"tag":2668,"props":2669,"children":2670},"style",{},[2671],{"type":37,"value":2672},"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":136,"depth":136,"links":2674},[2675,2676,2677,2678,2679,2680,2681,2682],{"id":42,"depth":92,"text":45},{"id":546,"depth":92,"text":549},{"id":677,"depth":92,"text":680},{"id":1202,"depth":92,"text":1205},{"id":2157,"depth":92,"text":2160},{"id":2303,"depth":92,"text":2306},{"id":2428,"depth":92,"text":2431},{"id":2486,"depth":92,"text":2489},"markdown","content:it:data:architettura-tabella-cohort-retention-production.md","content","it\u002Fdata\u002Farchitettura-tabella-cohort-retention-production.md","it\u002Fdata\u002Farchitettura-tabella-cohort-retention-production","md",1780898618086]