[{"data":1,"prerenderedAt":2689},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fes\u002Fdata\u002Farquitectura-tabla-cohort":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":8,"_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,"","Arquitectura de Tabla Cohort: Escalado de Análisis de Retención en Production","Materialized views, partitioning y query cost optimization para ejecutar cohort analysis sobre millones de usuarios: arquitectura BigQuery production-ready.","2026-05-22",[21,22,23,24,25],"analisis-cohort","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","El análisis de retención es uno de los métodos más poderosos para entender el comportamiento del usuario. Pero a escala real —millones de eventos diarios, cientos de miles de usuarios— las consultas SQL ingenuas se agotan en 30 segundos o consumen toda la capacidad de slots. La retención sostenible en production requiere optimizar la arquitectura de la tabla según el motor de consultas. En este artículo te mostramos cómo escalar tablas cohort en BigQuery usando materialized views, partitioning e incremental refresh strategies.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"por-qué-la-consulta-cohort-ingenua-falla",[44],{"type":37,"value":45},"Por qué la Consulta Cohort Ingenua Falla",{"type":32,"tag":33,"props":47,"children":48},{},[49],{"type":37,"value":50},"El análisis cohort clásico funciona así: encuentra la fecha de primera actividad del usuario (cohort_date), calcula todas las actividades posteriores como \"Día N\" respecto a esa fecha, suma tasas de retención por grupo. El siguiente SQL es lógicamente correcto pero no funciona en production:",{"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},"Hay dos grandes problemas aquí: (1) la tabla ",{"type":32,"tag":59,"props":537,"children":539},{"className":538},[],[540],{"type":37,"value":541},"events",{"type":37,"value":543}," se escanea completa en cada ejecución —sin partition pruning—, (2) para cada cohort_date se hace join de todas las actividades de todos los usuarios —riesgo de explosión cartesiana. Con 100M eventos, esta consulta procesa 400GB de datos y termina en 2 minutos; pero en refresh diario no es sostenible. La factura de BigQuery crece 10x antes de fin de mes.",{"type":32,"tag":40,"props":545,"children":547},{"id":546},"tabla-base-particionada-para-reducir-carga-de-filtrado",[548],{"type":37,"value":549},"Tabla Base Particionada para Reducir Carga de Filtrado",{"type":32,"tag":33,"props":551,"children":552},{},[553,555,560,562,568,570,576],{"type":37,"value":554},"El primer paso: particionar la tabla ",{"type":32,"tag":59,"props":556,"children":558},{"className":557},[],[559],{"type":37,"value":541},{"type":37,"value":561}," por ",{"type":32,"tag":59,"props":563,"children":565},{"className":564},[],[566],{"type":37,"value":567},"DATE(event_timestamp)",{"type":37,"value":569},". Esto garantiza que cuando la consulta incluya ",{"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},", solo las particiones relevantes se escaneen:",{"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},"El clustering en (user_id, event_name) coloca los eventos del mismo usuario en bloques físicamente cercanos —el rendimiento del join mejora 30-50%. Pero esto solo no es suficiente; la lógica de cálculo cohort se repite en cada consulta. Aquí entra la materialized view.",{"type":32,"tag":40,"props":676,"children":678},{"id":677},"materialized-view-tabla-cohort-incremental",[679],{"type":37,"value":680},"Materialized View: Tabla Cohort Incremental",{"type":32,"tag":33,"props":682,"children":683},{},[684],{"type":37,"value":685},"Las materialized views de BigQuery almacenan físicamente el resultado de una consulta y se refresca automáticamente cuando cambian los datos base. Para análisis cohort usamos esta estructura:",{"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},"Esta view calcula una sola vez la fecha de primer evento de cada usuario (cohort_date) y la almacena. Cuando llegan eventos nuevos, BigQuery solo procesa el delta —no hay escaneo completo. La partición por cohort_date permite pruning en filtros como ",{"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},"Ahora la consulta de retención se reduce 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},"Esta consulta usa la materialized view en lugar de la tabla base —las filas a escanear se reducen de millones a miles. Pero aún procesa toda la tabla de eventos. El siguiente nivel es pre-agregar la retención.",{"type":32,"tag":40,"props":1201,"children":1203},{"id":1202},"tabla-de-retención-pre-agregada-capa-final",[1204],{"type":37,"value":1205},"Tabla de Retención Pre-Agregada: Capa Final",{"type":32,"tag":33,"props":1207,"children":1208},{},[1209],{"type":37,"value":1210},"El análisis cohort típicamente se ve en intervalos fijos —\"Día 0, Día 1, Día 7, Día 30\"— no hay necesidad de recalcular para cada día. Con dbt implementamos esta lógica:",{"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},"Cada día, extrae cohorts nuevos de la 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},"Para cada cohort calcula retención histórica de los últimos 30 días (que no cambia después del día 30)",{"type":32,"tag":1216,"props":1233,"children":1234},{},[1235,1237,1243,1245],{"type":37,"value":1236},"Escribe el resultado en ",{"type":32,"tag":59,"props":1238,"children":1240},{"className":1239},[],[1241],{"type":37,"value":1242},"cohort_retention_summary",{"type":37,"value":1244}," de forma ",{"type":32,"tag":1246,"props":1247,"children":1248},"strong",{},[1249],{"type":37,"value":1250},"incremental",{"type":32,"tag":33,"props":1252,"children":1253},{},[1254],{"type":37,"value":1255},"Modelo 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},"Este modelo actualiza solo los cohorts de los últimos 31 días cada día. Los cohorts más antiguos tienen retención fija —no se recalculan. El uso de slots baja 95%. ",{"type":32,"tag":2145,"props":2146,"children":2150},"a",{"href":2147,"rel":2148},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Fretention-engineering-cdp",[2149],"nofollow",[2151],{"type":37,"value":2152},"CDP & Retention Engineering",{"type":37,"value":2154}," se conecta directamente a esta tabla —las herramientas BI (Looker, Metabase) devuelven resultados en 100ms.",{"type":32,"tag":40,"props":2156,"children":2158},{"id":2157},"estrategia-de-query-cost-y-partition-expiration",[2159],{"type":37,"value":2160},"Estrategia de Query Cost y Partition Expiration",{"type":32,"tag":33,"props":2162,"children":2163},{},[2164],{"type":37,"value":2165},"En BigQuery, el storage es barato ($0.02\u002FGB\u002Fmes), el compute es caro ($5\u002FTB de datos procesados). El análisis de retención es retrospectivo, así que las particiones antiguas se escanean frecuentemente. Dos optimizaciones:",{"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}," Elimina automáticamente particiones de más de 90 días en ",{"type":32,"tag":59,"props":2180,"children":2182},{"className":2181},[],[2183],{"type":37,"value":541},{"type":37,"value":2185}," —no hay necesidad de raw events después del cálculo cohort.",{"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},"Actualiza estadísticas de clustering periódicamente:",{"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}," —el query optimizer elige mejor plan de ejecución.",{"type":32,"tag":33,"props":2205,"children":2206},{},[2207],{"type":37,"value":2208},"Comparación de costos (100M eventos\u002Fdía, 1M usuarios):",{"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},"Método",{"type":32,"tag":2222,"props":2228,"children":2229},{},[2230],{"type":37,"value":2231},"Datos procesados\u002Fdía",{"type":32,"tag":2222,"props":2233,"children":2234},{},[2235],{"type":37,"value":2236},"Compute mensual",{"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},"Consulta 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},"Particionado + 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},"Tabla pre-agregada (incremental)",{"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.5",{"type":32,"tag":33,"props":2297,"children":2298},{},[2299],{"type":37,"value":2300},"Agregar la capa pre-agregada reduce el compute 240x. Esta diferencia es crítica en production —especialmente si refresh es cada hora.",{"type":32,"tag":40,"props":2302,"children":2304},{"id":2303},"trade-off-de-análisis-cohort-en-tiempo-real",[2305],{"type":37,"value":2306},"Trade-off de Análisis Cohort en Tiempo Real",{"type":32,"tag":33,"props":2308,"children":2309},{},[2310],{"type":37,"value":2311},"La estructura de materialized view y pre-agregado introduce latencia: los datos se atrasan 1-5 minutos. Si necesitas retención en tiempo real (por ejemplo, para las primeras 24 horas), usa un enfoque híbrido:",{"type":32,"tag":2313,"props":2314,"children":2315},"ul",{},[2316,2321],{"type":32,"tag":1216,"props":2317,"children":2318},{},[2319],{"type":37,"value":2320},"Últimas 24 horas: streaming insert + real-time query (sin cache)",{"type":32,"tag":1216,"props":2322,"children":2323},{},[2324],{"type":37,"value":2325},"Datos más antiguos: tabla pre-agregada",{"type":32,"tag":33,"props":2327,"children":2328},{},[2329],{"type":37,"value":2330},"La consulta BI combina ambas fuentes 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},"Aunque la view en tiempo real es costosa, solo procesa el cohort actual —el impacto en compute total es limitado.",{"type":32,"tag":40,"props":2427,"children":2429},{"id":2428},"segmentación-de-cohort-y-explosión-de-cardinalidad",[2430],{"type":37,"value":2431},"Segmentación de Cohort y Explosión de Cardinalidad",{"type":32,"tag":33,"props":2433,"children":2434},{},[2435],{"type":37,"value":2436},"Dividir análisis de retención por segmentos de usuario (plataforma, país, channel de adquisición) puede dispara problemas de cardinalidad. Por ejemplo, 5 segmentos × 30 días × 365 cohorts = 54.750 filas únicas. En este 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 segmentos:",{"type":37,"value":2449}," Analiza solo los 3-5 más importantes; crea tablas separadas para otros.",{"type":32,"tag":1216,"props":2451,"children":2452},{},[2453,2458],{"type":32,"tag":1246,"props":2454,"children":2455},{},[2456],{"type":37,"value":2457},"Segmentación dinámica:",{"type":37,"value":2459}," En lugar de agregar segmento a la tabla pre-agregada, filtra en join-time —mantiene flexibilidad pero aumenta uso de slots.",{"type":32,"tag":1216,"props":2461,"children":2462},{},[2463,2468],{"type":32,"tag":1246,"props":2464,"children":2465},{},[2466],{"type":37,"value":2467},"Tabla rollup:",{"type":37,"value":2469}," Crea tabla separada para cohorts semanales (weekly_cohort_retention) —cardinalidad baja 85%.",{"type":32,"tag":33,"props":2471,"children":2472},{},[2473,2475,2482],{"type":37,"value":2474},"En el proceso ",{"type":32,"tag":2145,"props":2476,"children":2479},{"href":2477,"rel":2478},"https:\u002F\u002Fwww.roibase.com.tr\u002Fes\u002Fverianalizi",[2149],[2480],{"type":37,"value":2481},"Veri Analizi & İçgörü Mühendisliği",{"type":37,"value":2483}," de Roibase, integramos estrategia de segmentación con attribution de fuente de adquisición —la retención se vincula directamente con desempeño de canal.",{"type":32,"tag":40,"props":2485,"children":2487},{"id":2486},"monitoreo-y-detección-de-regresión",[2488],{"type":37,"value":2489},"Monitoreo y Detección de Regresión",{"type":32,"tag":33,"props":2491,"children":2492},{},[2493],{"type":37,"value":2494},"Monitorea el pipeline cohort en production con estas métricas:",{"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}," El uso de slots en refresh diario —un aumento súbito indica explosión de cardinalidad o pérdida de 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}," Filas agregadas en cada refresh —más de lo esperado significa riesgo de eventos duplicados.",{"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}," Un cambio >10% en retención del Día 1 señala problema de calidad de datos.",{"type":32,"tag":33,"props":2529,"children":2530},{},[2531],{"type":37,"value":2532},"Agrega estos checks como tests en 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},"Si falla un test, activa alerta Slack\u002FPagerDuty —sin esperar revisión manual.",{"type":32,"tag":33,"props":2663,"children":2664},{},[2665],{"type":37,"value":2666},"La arquitectura de tabla cohort traslada análisis de retención de \"consulta ad-hoc\" a \"data product de production\". Refresh incremental con materialized view, partition pruning, optimización de slots con pre-agregado —cada capa reduce costos 10x. Analizar retención sobre millones de usuarios y miles de millones de eventos ahora se resume en query de dashboard en 100ms. Decidir qué patrones de retención monitorear sigue siendo tu trabajo —pero procesar datos a esa velocidad ya no es un problema de ingeniería.",{"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:es:data:arquitectura-tabla-cohort.md","content","es\u002Fdata\u002Farquitectura-tabla-cohort.md","es\u002Fdata\u002Farquitectura-tabla-cohort","md",1780898614119]