[{"data":1,"prerenderedAt":2496},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fru\u002Fdata\u002Fcohort-table-architecture-scaling-retention":13},{"i18nKey":4,"paths":5},"data-007-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fen\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fes\u002Fdata\u002Farquitectura-tabla-cohorte-escalando-analisis-retencion","\u002Ffr\u002Fdata\u002Farchitecture-table-cohort-retention-optimisation-production","\u002Fit\u002Fdata\u002Farchitettura-tabella-cohort-scalabilita-retention-analysis-production","\u002Fru\u002Fdata\u002Fcohort-table-architecture-scaling-retention","\u002Ftr\u002Fdata\u002Fcohort-tablo-mimarisi-retention-analizinin-productionda-olceklenmesi",{"_path":11,"_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":2490,"_id":2491,"_source":2492,"_file":2493,"_stem":2494,"_extension":2495},"data",false,"","Архитектура таблиц когорт: масштабирование анализа удержания в production","Узнайте, как масштабировать таблицы когортного анализа в production с помощью materialized views, partitioning и оптимизации затрат запросов.","2026-07-28",[21,22,23,24,25],"когортный-анализ","bigquery","materialized-views","data-engineering","retention",9,"Roibase",{"type":29,"children":30,"toc":2475},"root",[31,48,55,83,510,523,528,535,540,623,643,677,682,688,707,896,901,943,948,1199,1211,1217,1230,1546,1551,1557,1569,1896,1900,1946,1959,1965,1992,2000,2026,2034,2059,2075,2081,2086,2139,2152,2179,2184,2201,2207,2220,2225,2261,2282,2288,2293,2316,2327,2374,2391,2402,2440,2457,2469],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,46],{"type":37,"value":38},"text","Каждая организация, занимающаяся анализом удержания пользователей, сталкивается с одной и той же проблемой: запросы когорт либо выполняются 30 секунд в production, либо счет BigQuery приближается к $8.000 в месяц. Запрос ",{"type":32,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":37,"value":45},"GROUP BY user_id, cohort_week",{"type":37,"value":47},", который хорошо работает на 100K пользователей в тестовом окружении, падает, когда встречает 50M пользователей и 2 года логов событий. Решение не простое — недостаточно добавить индекс или включить кеш. Нужно с нуля спроектировать архитектуру таблицы под workload анализа удержания.",{"type":32,"tag":49,"props":50,"children":52},"h2",{"id":51},"почему-когортный-анализ-требует-отдельной-архитектуры",[53],{"type":37,"value":54},"Почему когортный анализ требует отдельной архитектуры",{"type":32,"tag":33,"props":56,"children":57},{},[58,60,66,68,74,75,81],{"type":37,"value":59},"Стандартная таблица event log построена на ",{"type":32,"tag":40,"props":61,"children":63},{"className":62},[],[64],{"type":37,"value":65},"user_id",{"type":37,"value":67},", ",{"type":32,"tag":40,"props":69,"children":71},{"className":70},[],[72],{"type":37,"value":73},"event_time",{"type":37,"value":67},{"type":32,"tag":40,"props":76,"children":78},{"className":77},[],[79],{"type":37,"value":80},"event_name",{"type":37,"value":82},". Каждый когортный запрос сканирует миллиарды строк в этой таблице исторически, группируя пользователя по дате первого события. В BigQuery запрос выглядит так:",{"type":32,"tag":84,"props":85,"children":89},"pre",{"className":86,"code":87,"language":88,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","WITH cohorts AS (\n  SELECT user_id, DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week\n  FROM events\n  GROUP BY user_id\n),\nretention AS (\n  SELECT \n    c.cohort_week,\n    DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since_cohort,\n    COUNT(DISTINCT e.user_id) AS active_users\n  FROM cohorts c\n  JOIN events e ON c.user_id = e.user_id\n  GROUP BY 1, 2\n)\nSELECT * FROM retention ORDER BY 1, 2;\n","sql",[90],{"type":32,"tag":40,"props":91,"children":92},{"__ignoreMap":16},[93,121,165,179,193,202,219,232,256,324,369,382,432,454,463],{"type":32,"tag":94,"props":95,"children":98},"span",{"class":96,"line":97},"line",1,[99,105,111,116],{"type":32,"tag":94,"props":100,"children":102},{"style":101},"--shiki-default:#F97583",[103],{"type":37,"value":104},"WITH",{"type":32,"tag":94,"props":106,"children":108},{"style":107},"--shiki-default:#E1E4E8",[109],{"type":37,"value":110}," cohorts ",{"type":32,"tag":94,"props":112,"children":113},{"style":101},[114],{"type":37,"value":115},"AS",{"type":32,"tag":94,"props":117,"children":118},{"style":107},[119],{"type":37,"value":120}," (\n",{"type":32,"tag":94,"props":122,"children":124},{"class":96,"line":123},2,[125,130,135,141,146,151,156,160],{"type":32,"tag":94,"props":126,"children":127},{"style":101},[128],{"type":37,"value":129},"  SELECT",{"type":32,"tag":94,"props":131,"children":132},{"style":107},[133],{"type":37,"value":134}," user_id, DATE_TRUNC(",{"type":32,"tag":94,"props":136,"children":138},{"style":137},"--shiki-default:#79B8FF",[139],{"type":37,"value":140},"MIN",{"type":32,"tag":94,"props":142,"children":143},{"style":107},[144],{"type":37,"value":145},"(event_time), ",{"type":32,"tag":94,"props":147,"children":148},{"style":101},[149],{"type":37,"value":150},"WEEK",{"type":32,"tag":94,"props":152,"children":153},{"style":107},[154],{"type":37,"value":155},") ",{"type":32,"tag":94,"props":157,"children":158},{"style":101},[159],{"type":37,"value":115},{"type":32,"tag":94,"props":161,"children":162},{"style":107},[163],{"type":37,"value":164}," cohort_week\n",{"type":32,"tag":94,"props":166,"children":168},{"class":96,"line":167},3,[169,174],{"type":32,"tag":94,"props":170,"children":171},{"style":101},[172],{"type":37,"value":173},"  FROM",{"type":32,"tag":94,"props":175,"children":176},{"style":107},[177],{"type":37,"value":178}," events\n",{"type":32,"tag":94,"props":180,"children":182},{"class":96,"line":181},4,[183,188],{"type":32,"tag":94,"props":184,"children":185},{"style":101},[186],{"type":37,"value":187},"  GROUP BY",{"type":32,"tag":94,"props":189,"children":190},{"style":107},[191],{"type":37,"value":192}," user_id\n",{"type":32,"tag":94,"props":194,"children":196},{"class":96,"line":195},5,[197],{"type":32,"tag":94,"props":198,"children":199},{"style":107},[200],{"type":37,"value":201},"),\n",{"type":32,"tag":94,"props":203,"children":205},{"class":96,"line":204},6,[206,210,215],{"type":32,"tag":94,"props":207,"children":208},{"style":101},[209],{"type":37,"value":25},{"type":32,"tag":94,"props":211,"children":212},{"style":101},[213],{"type":37,"value":214}," AS",{"type":32,"tag":94,"props":216,"children":217},{"style":107},[218],{"type":37,"value":120},{"type":32,"tag":94,"props":220,"children":222},{"class":96,"line":221},7,[223,227],{"type":32,"tag":94,"props":224,"children":225},{"style":101},[226],{"type":37,"value":129},{"type":32,"tag":94,"props":228,"children":229},{"style":107},[230],{"type":37,"value":231}," \n",{"type":32,"tag":94,"props":233,"children":235},{"class":96,"line":234},8,[236,241,246,251],{"type":32,"tag":94,"props":237,"children":238},{"style":137},[239],{"type":37,"value":240},"    c",{"type":32,"tag":94,"props":242,"children":243},{"style":107},[244],{"type":37,"value":245},".",{"type":32,"tag":94,"props":247,"children":248},{"style":137},[249],{"type":37,"value":250},"cohort_week",{"type":32,"tag":94,"props":252,"children":253},{"style":107},[254],{"type":37,"value":255},",\n",{"type":32,"tag":94,"props":257,"children":258},{"class":96,"line":26},[259,264,269,273,277,281,285,290,295,299,303,307,311,315,319],{"type":32,"tag":94,"props":260,"children":261},{"style":107},[262],{"type":37,"value":263},"    DATE_DIFF(DATE_TRUNC(",{"type":32,"tag":94,"props":265,"children":266},{"style":137},[267],{"type":37,"value":268},"e",{"type":32,"tag":94,"props":270,"children":271},{"style":107},[272],{"type":37,"value":245},{"type":32,"tag":94,"props":274,"children":275},{"style":137},[276],{"type":37,"value":73},{"type":32,"tag":94,"props":278,"children":279},{"style":107},[280],{"type":37,"value":67},{"type":32,"tag":94,"props":282,"children":283},{"style":101},[284],{"type":37,"value":150},{"type":32,"tag":94,"props":286,"children":287},{"style":107},[288],{"type":37,"value":289},"), ",{"type":32,"tag":94,"props":291,"children":292},{"style":137},[293],{"type":37,"value":294},"c",{"type":32,"tag":94,"props":296,"children":297},{"style":107},[298],{"type":37,"value":245},{"type":32,"tag":94,"props":300,"children":301},{"style":137},[302],{"type":37,"value":250},{"type":32,"tag":94,"props":304,"children":305},{"style":107},[306],{"type":37,"value":67},{"type":32,"tag":94,"props":308,"children":309},{"style":101},[310],{"type":37,"value":150},{"type":32,"tag":94,"props":312,"children":313},{"style":107},[314],{"type":37,"value":155},{"type":32,"tag":94,"props":316,"children":317},{"style":101},[318],{"type":37,"value":115},{"type":32,"tag":94,"props":320,"children":321},{"style":107},[322],{"type":37,"value":323}," weeks_since_cohort,\n",{"type":32,"tag":94,"props":325,"children":327},{"class":96,"line":326},10,[328,333,338,343,348,352,356,360,364],{"type":32,"tag":94,"props":329,"children":330},{"style":137},[331],{"type":37,"value":332},"    COUNT",{"type":32,"tag":94,"props":334,"children":335},{"style":107},[336],{"type":37,"value":337},"(",{"type":32,"tag":94,"props":339,"children":340},{"style":101},[341],{"type":37,"value":342},"DISTINCT",{"type":32,"tag":94,"props":344,"children":345},{"style":137},[346],{"type":37,"value":347}," e",{"type":32,"tag":94,"props":349,"children":350},{"style":107},[351],{"type":37,"value":245},{"type":32,"tag":94,"props":353,"children":354},{"style":137},[355],{"type":37,"value":65},{"type":32,"tag":94,"props":357,"children":358},{"style":107},[359],{"type":37,"value":155},{"type":32,"tag":94,"props":361,"children":362},{"style":101},[363],{"type":37,"value":115},{"type":32,"tag":94,"props":365,"children":366},{"style":107},[367],{"type":37,"value":368}," active_users\n",{"type":32,"tag":94,"props":370,"children":372},{"class":96,"line":371},11,[373,377],{"type":32,"tag":94,"props":374,"children":375},{"style":101},[376],{"type":37,"value":173},{"type":32,"tag":94,"props":378,"children":379},{"style":107},[380],{"type":37,"value":381}," cohorts c\n",{"type":32,"tag":94,"props":383,"children":385},{"class":96,"line":384},12,[386,391,396,401,406,410,414,419,423,427],{"type":32,"tag":94,"props":387,"children":388},{"style":101},[389],{"type":37,"value":390},"  JOIN",{"type":32,"tag":94,"props":392,"children":393},{"style":107},[394],{"type":37,"value":395}," events e ",{"type":32,"tag":94,"props":397,"children":398},{"style":101},[399],{"type":37,"value":400},"ON",{"type":32,"tag":94,"props":402,"children":403},{"style":137},[404],{"type":37,"value":405}," c",{"type":32,"tag":94,"props":407,"children":408},{"style":107},[409],{"type":37,"value":245},{"type":32,"tag":94,"props":411,"children":412},{"style":137},[413],{"type":37,"value":65},{"type":32,"tag":94,"props":415,"children":416},{"style":101},[417],{"type":37,"value":418}," =",{"type":32,"tag":94,"props":420,"children":421},{"style":137},[422],{"type":37,"value":347},{"type":32,"tag":94,"props":424,"children":425},{"style":107},[426],{"type":37,"value":245},{"type":32,"tag":94,"props":428,"children":429},{"style":137},[430],{"type":37,"value":431},"user_id\n",{"type":32,"tag":94,"props":433,"children":435},{"class":96,"line":434},13,[436,440,445,449],{"type":32,"tag":94,"props":437,"children":438},{"style":101},[439],{"type":37,"value":187},{"type":32,"tag":94,"props":441,"children":442},{"style":137},[443],{"type":37,"value":444}," 1",{"type":32,"tag":94,"props":446,"children":447},{"style":107},[448],{"type":37,"value":67},{"type":32,"tag":94,"props":450,"children":451},{"style":137},[452],{"type":37,"value":453},"2\n",{"type":32,"tag":94,"props":455,"children":457},{"class":96,"line":456},14,[458],{"type":32,"tag":94,"props":459,"children":460},{"style":107},[461],{"type":37,"value":462},")\n",{"type":32,"tag":94,"props":464,"children":466},{"class":96,"line":465},15,[467,472,477,482,487,492,496,500,505],{"type":32,"tag":94,"props":468,"children":469},{"style":101},[470],{"type":37,"value":471},"SELECT",{"type":32,"tag":94,"props":473,"children":474},{"style":101},[475],{"type":37,"value":476}," *",{"type":32,"tag":94,"props":478,"children":479},{"style":101},[480],{"type":37,"value":481}," FROM",{"type":32,"tag":94,"props":483,"children":484},{"style":101},[485],{"type":37,"value":486}," retention",{"type":32,"tag":94,"props":488,"children":489},{"style":101},[490],{"type":37,"value":491}," ORDER BY",{"type":32,"tag":94,"props":493,"children":494},{"style":137},[495],{"type":37,"value":444},{"type":32,"tag":94,"props":497,"children":498},{"style":107},[499],{"type":37,"value":67},{"type":32,"tag":94,"props":501,"children":502},{"style":137},[503],{"type":37,"value":504},"2",{"type":32,"tag":94,"props":506,"children":507},{"style":107},[508],{"type":37,"value":509},";\n",{"type":32,"tag":33,"props":511,"children":512},{},[513,515,521],{"type":37,"value":514},"Каждый раз при выполнении этот запрос читает всю таблицу ",{"type":32,"tag":40,"props":516,"children":518},{"className":517},[],[519],{"type":37,"value":520},"events",{"type":37,"value":522},". 500M строк × 16 байт в среднем = 8 GB сканирования. В BigQuery 1 TB сканирования стоит $6.25, значит 1.000 запросов = $50. Если дашборд обновляется каждые 5 минут, то в месяц 8.640 запросов = $432 только на виджет когорт. Добавь еще 10 аналитиков, боты в Slack, и стоимость удваивается.",{"type":32,"tag":33,"props":524,"children":525},{},[526],{"type":37,"value":527},"Но проблема не только в стоимости — это задержка. JOIN с 500M строк занимает 15–30 секунд. Аналитик поменял фильтр на дашборде, ждет 20 секунд новых данных когорты. Анализ удержания на таких задержках не может быть итеративным.",{"type":32,"tag":529,"props":530,"children":532},"h3",{"id":531},"materialized-view-первый-шаг-но-недостаточно",[533],{"type":37,"value":534},"Materialized View — первый шаг, но недостаточно",{"type":32,"tag":33,"props":536,"children":537},{},[538],{"type":37,"value":539},"Materialized view в BigQuery предварительно вычисляет когортный запрос:",{"type":32,"tag":84,"props":541,"children":543},{"className":86,"code":542,"language":88,"meta":16,"style":16},"CREATE MATERIALIZED VIEW cohort_retention AS\nSELECT \n  cohort_week,\n  weeks_since_cohort,\n  active_users\nFROM retention; -- результат CTE-запроса выше\n",[544],{"type":32,"tag":40,"props":545,"children":546},{"__ignoreMap":16},[547,565,576,584,592,600],{"type":32,"tag":94,"props":548,"children":549},{"class":96,"line":97},[550,555,560],{"type":32,"tag":94,"props":551,"children":552},{"style":101},[553],{"type":37,"value":554},"CREATE",{"type":32,"tag":94,"props":556,"children":557},{"style":107},[558],{"type":37,"value":559}," MATERIALIZED VIEW cohort_retention ",{"type":32,"tag":94,"props":561,"children":562},{"style":101},[563],{"type":37,"value":564},"AS\n",{"type":32,"tag":94,"props":566,"children":567},{"class":96,"line":123},[568,572],{"type":32,"tag":94,"props":569,"children":570},{"style":101},[571],{"type":37,"value":471},{"type":32,"tag":94,"props":573,"children":574},{"style":107},[575],{"type":37,"value":231},{"type":32,"tag":94,"props":577,"children":578},{"class":96,"line":167},[579],{"type":32,"tag":94,"props":580,"children":581},{"style":107},[582],{"type":37,"value":583},"  cohort_week,\n",{"type":32,"tag":94,"props":585,"children":586},{"class":96,"line":181},[587],{"type":32,"tag":94,"props":588,"children":589},{"style":107},[590],{"type":37,"value":591},"  weeks_since_cohort,\n",{"type":32,"tag":94,"props":593,"children":594},{"class":96,"line":195},[595],{"type":32,"tag":94,"props":596,"children":597},{"style":107},[598],{"type":37,"value":599},"  active_users\n",{"type":32,"tag":94,"props":601,"children":602},{"class":96,"line":204},[603,608,612,617],{"type":32,"tag":94,"props":604,"children":605},{"style":101},[606],{"type":37,"value":607},"FROM",{"type":32,"tag":94,"props":609,"children":610},{"style":101},[611],{"type":37,"value":486},{"type":32,"tag":94,"props":613,"children":614},{"style":107},[615],{"type":37,"value":616},"; ",{"type":32,"tag":94,"props":618,"children":620},{"style":619},"--shiki-default:#6A737D",[621],{"type":37,"value":622},"-- результат CTE-запроса выше\n",{"type":32,"tag":33,"props":624,"children":625},{},[626,628,634,636,641],{"type":37,"value":627},"Теперь дашборд читает ",{"type":32,"tag":40,"props":629,"children":631},{"className":630},[],[632],{"type":37,"value":633},"cohort_retention",{"type":37,"value":635},", а не ",{"type":32,"tag":40,"props":637,"children":639},{"className":638},[],[640],{"type":37,"value":520},{"type":37,"value":642},". Сканирование 8 GB вместо 80 MB. Задержка 20 секунд вместо 800 ms. Но есть два ограничения:",{"type":32,"tag":644,"props":645,"children":646},"ol",{},[647,659],{"type":32,"tag":648,"props":649,"children":650},"li",{},[651,657],{"type":32,"tag":652,"props":653,"children":654},"strong",{},[655],{"type":37,"value":656},"Стоимость обновления:",{"type":37,"value":658}," Materialized view при каждом refresh'е выполняет базовый запрос. То есть снова 8 GB сканирования. Если обновлять view каждый час, получится 24 × 8 GB = 192 GB\u002Fдень = 5,8 TB\u002Fмесяц сканирования. Стоимость не снизилась, только задержка.",{"type":32,"tag":648,"props":660,"children":661},{},[662,667,669,675],{"type":32,"tag":652,"props":663,"children":664},{},[665],{"type":37,"value":666},"Гибкость:",{"type":37,"value":668}," Materialized view статичен. Если аналитик добавит фильтр \"retention Android-когорты\", view нужно пересчитать. Нельзя добавить pre-filter, потому что ",{"type":32,"tag":40,"props":670,"children":672},{"className":671},[],[673],{"type":37,"value":674},"WHERE platform = 'Android'",{"type":37,"value":676}," потребует другого view.",{"type":32,"tag":33,"props":678,"children":679},{},[680],{"type":37,"value":681},"Поэтому архитектура когорт должна быть трёхслойной: raw events → таблица назначения когорт → таблица агрегированного удержания.",{"type":32,"tag":49,"props":683,"children":685},{"id":684},"отдельная-таблица-назначения-когорт",[686],{"type":37,"value":687},"Отдельная таблица назначения когорт",{"type":32,"tag":33,"props":689,"children":690},{},[691,693,698,700,705],{"type":37,"value":692},"Первый шаг: создай отдельную таблицу, которая присваивает каждого пользователя его когорте. Эта таблица содержит только ",{"type":32,"tag":40,"props":694,"children":696},{"className":695},[],[697],{"type":37,"value":65},{"type":37,"value":699}," и ",{"type":32,"tag":40,"props":701,"children":703},{"className":702},[],[704],{"type":37,"value":250},{"type":37,"value":706},", вычисляется из event log, но обновляется один раз в день:",{"type":32,"tag":84,"props":708,"children":710},{"className":86,"code":709,"language":88,"meta":16,"style":16},"CREATE OR REPLACE TABLE cohort_assignments\nPARTITION BY cohort_week\nCLUSTER BY user_id\nAS\nSELECT \n  user_id,\n  DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week,\n  MIN(event_time) AS first_seen_at\nFROM events\nWHERE event_time >= '2024-01-01'\nGROUP BY user_id;\n",[711],{"type":32,"tag":40,"props":712,"children":713},{"__ignoreMap":16},[714,733,750,767,774,785,793,826,848,859,883],{"type":32,"tag":94,"props":715,"children":716},{"class":96,"line":97},[717,722,727],{"type":32,"tag":94,"props":718,"children":719},{"style":101},[720],{"type":37,"value":721},"CREATE OR REPLACE",{"type":32,"tag":94,"props":723,"children":724},{"style":101},[725],{"type":37,"value":726}," TABLE",{"type":32,"tag":94,"props":728,"children":730},{"style":729},"--shiki-default:#B392F0",[731],{"type":37,"value":732}," cohort_assignments\n",{"type":32,"tag":94,"props":734,"children":735},{"class":96,"line":123},[736,741,746],{"type":32,"tag":94,"props":737,"children":738},{"style":101},[739],{"type":37,"value":740},"PARTITION",{"type":32,"tag":94,"props":742,"children":743},{"style":101},[744],{"type":37,"value":745}," BY",{"type":32,"tag":94,"props":747,"children":748},{"style":107},[749],{"type":37,"value":164},{"type":32,"tag":94,"props":751,"children":752},{"class":96,"line":167},[753,758,763],{"type":32,"tag":94,"props":754,"children":755},{"style":107},[756],{"type":37,"value":757},"CLUSTER ",{"type":32,"tag":94,"props":759,"children":760},{"style":101},[761],{"type":37,"value":762},"BY",{"type":32,"tag":94,"props":764,"children":765},{"style":107},[766],{"type":37,"value":192},{"type":32,"tag":94,"props":768,"children":769},{"class":96,"line":181},[770],{"type":32,"tag":94,"props":771,"children":772},{"style":101},[773],{"type":37,"value":564},{"type":32,"tag":94,"props":775,"children":776},{"class":96,"line":195},[777,781],{"type":32,"tag":94,"props":778,"children":779},{"style":101},[780],{"type":37,"value":471},{"type":32,"tag":94,"props":782,"children":783},{"style":107},[784],{"type":37,"value":231},{"type":32,"tag":94,"props":786,"children":787},{"class":96,"line":204},[788],{"type":32,"tag":94,"props":789,"children":790},{"style":107},[791],{"type":37,"value":792},"  user_id,\n",{"type":32,"tag":94,"props":794,"children":795},{"class":96,"line":221},[796,801,805,809,813,817,821],{"type":32,"tag":94,"props":797,"children":798},{"style":107},[799],{"type":37,"value":800},"  DATE_TRUNC(",{"type":32,"tag":94,"props":802,"children":803},{"style":137},[804],{"type":37,"value":140},{"type":32,"tag":94,"props":806,"children":807},{"style":107},[808],{"type":37,"value":145},{"type":32,"tag":94,"props":810,"children":811},{"style":101},[812],{"type":37,"value":150},{"type":32,"tag":94,"props":814,"children":815},{"style":107},[816],{"type":37,"value":155},{"type":32,"tag":94,"props":818,"children":819},{"style":101},[820],{"type":37,"value":115},{"type":32,"tag":94,"props":822,"children":823},{"style":107},[824],{"type":37,"value":825}," cohort_week,\n",{"type":32,"tag":94,"props":827,"children":828},{"class":96,"line":234},[829,834,839,843],{"type":32,"tag":94,"props":830,"children":831},{"style":137},[832],{"type":37,"value":833},"  MIN",{"type":32,"tag":94,"props":835,"children":836},{"style":107},[837],{"type":37,"value":838},"(event_time) ",{"type":32,"tag":94,"props":840,"children":841},{"style":101},[842],{"type":37,"value":115},{"type":32,"tag":94,"props":844,"children":845},{"style":107},[846],{"type":37,"value":847}," first_seen_at\n",{"type":32,"tag":94,"props":849,"children":850},{"class":96,"line":26},[851,855],{"type":32,"tag":94,"props":852,"children":853},{"style":101},[854],{"type":37,"value":607},{"type":32,"tag":94,"props":856,"children":857},{"style":107},[858],{"type":37,"value":178},{"type":32,"tag":94,"props":860,"children":861},{"class":96,"line":326},[862,867,872,877],{"type":32,"tag":94,"props":863,"children":864},{"style":101},[865],{"type":37,"value":866},"WHERE",{"type":32,"tag":94,"props":868,"children":869},{"style":107},[870],{"type":37,"value":871}," event_time ",{"type":32,"tag":94,"props":873,"children":874},{"style":101},[875],{"type":37,"value":876},">=",{"type":32,"tag":94,"props":878,"children":880},{"style":879},"--shiki-default:#9ECBFF",[881],{"type":37,"value":882}," '2024-01-01'\n",{"type":32,"tag":94,"props":884,"children":885},{"class":96,"line":371},[886,891],{"type":32,"tag":94,"props":887,"children":888},{"style":101},[889],{"type":37,"value":890},"GROUP BY",{"type":32,"tag":94,"props":892,"children":893},{"style":107},[894],{"type":37,"value":895}," user_id;\n",{"type":32,"tag":33,"props":897,"children":898},{},[899],{"type":37,"value":900},"Эта таблица:",{"type":32,"tag":902,"props":903,"children":904},"ul",{},[905,923,933],{"type":32,"tag":648,"props":906,"children":907},{},[908,913,915,921],{"type":32,"tag":652,"props":909,"children":910},{},[911],{"type":37,"value":912},"Partitioned by cohort_week:",{"type":37,"value":914}," BigQuery создает отдельный блок файла для каждой недели. Фильтр ",{"type":32,"tag":40,"props":916,"children":918},{"className":917},[],[919],{"type":37,"value":920},"WHERE cohort_week = '2026-01-05'",{"type":37,"value":922}," читает только одну партицию.",{"type":32,"tag":648,"props":924,"children":925},{},[926,931],{"type":32,"tag":652,"props":927,"children":928},{},[929],{"type":37,"value":930},"Clustered by user_id:",{"type":37,"value":932}," Внутри партиции данные отсортированы по user_id. JOIN ускоряется.",{"type":32,"tag":648,"props":934,"children":935},{},[936,941],{"type":32,"tag":652,"props":937,"children":938},{},[939],{"type":37,"value":940},"Размер:",{"type":37,"value":942}," 50M пользователей × 3 колонки × 16 байт = ~2.4 GB. Если event log 500 GB, эта таблица в 200× меньше.",{"type":32,"tag":33,"props":944,"children":945},{},[946],{"type":37,"value":947},"Теперь запрос удержания использует эту таблицу:",{"type":32,"tag":84,"props":949,"children":951},{"className":86,"code":950,"language":88,"meta":16,"style":16},"SELECT \n  c.cohort_week,\n  DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since,\n  COUNT(DISTINCT e.user_id) AS active_users\nFROM cohort_assignments c\nJOIN events e ON c.user_id = e.user_id\nWHERE c.cohort_week >= '2026-01-01'\nGROUP BY 1, 2;\n",[952],{"type":32,"tag":40,"props":953,"children":954},{"__ignoreMap":16},[955,966,986,1051,1091,1103,1147,1176],{"type":32,"tag":94,"props":956,"children":957},{"class":96,"line":97},[958,962],{"type":32,"tag":94,"props":959,"children":960},{"style":101},[961],{"type":37,"value":471},{"type":32,"tag":94,"props":963,"children":964},{"style":107},[965],{"type":37,"value":231},{"type":32,"tag":94,"props":967,"children":968},{"class":96,"line":123},[969,974,978,982],{"type":32,"tag":94,"props":970,"children":971},{"style":137},[972],{"type":37,"value":973},"  c",{"type":32,"tag":94,"props":975,"children":976},{"style":107},[977],{"type":37,"value":245},{"type":32,"tag":94,"props":979,"children":980},{"style":137},[981],{"type":37,"value":250},{"type":32,"tag":94,"props":983,"children":984},{"style":107},[985],{"type":37,"value":255},{"type":32,"tag":94,"props":987,"children":988},{"class":96,"line":167},[989,994,998,1002,1006,1010,1014,1018,1022,1026,1030,1034,1038,1042,1046],{"type":32,"tag":94,"props":990,"children":991},{"style":107},[992],{"type":37,"value":993},"  DATE_DIFF(DATE_TRUNC(",{"type":32,"tag":94,"props":995,"children":996},{"style":137},[997],{"type":37,"value":268},{"type":32,"tag":94,"props":999,"children":1000},{"style":107},[1001],{"type":37,"value":245},{"type":32,"tag":94,"props":1003,"children":1004},{"style":137},[1005],{"type":37,"value":73},{"type":32,"tag":94,"props":1007,"children":1008},{"style":107},[1009],{"type":37,"value":67},{"type":32,"tag":94,"props":1011,"children":1012},{"style":101},[1013],{"type":37,"value":150},{"type":32,"tag":94,"props":1015,"children":1016},{"style":107},[1017],{"type":37,"value":289},{"type":32,"tag":94,"props":1019,"children":1020},{"style":137},[1021],{"type":37,"value":294},{"type":32,"tag":94,"props":1023,"children":1024},{"style":107},[1025],{"type":37,"value":245},{"type":32,"tag":94,"props":1027,"children":1028},{"style":137},[1029],{"type":37,"value":250},{"type":32,"tag":94,"props":1031,"children":1032},{"style":107},[1033],{"type":37,"value":67},{"type":32,"tag":94,"props":1035,"children":1036},{"style":101},[1037],{"type":37,"value":150},{"type":32,"tag":94,"props":1039,"children":1040},{"style":107},[1041],{"type":37,"value":155},{"type":32,"tag":94,"props":1043,"children":1044},{"style":101},[1045],{"type":37,"value":115},{"type":32,"tag":94,"props":1047,"children":1048},{"style":107},[1049],{"type":37,"value":1050}," weeks_since,\n",{"type":32,"tag":94,"props":1052,"children":1053},{"class":96,"line":181},[1054,1059,1063,1067,1071,1075,1079,1083,1087],{"type":32,"tag":94,"props":1055,"children":1056},{"style":137},[1057],{"type":37,"value":1058},"  COUNT",{"type":32,"tag":94,"props":1060,"children":1061},{"style":107},[1062],{"type":37,"value":337},{"type":32,"tag":94,"props":1064,"children":1065},{"style":101},[1066],{"type":37,"value":342},{"type":32,"tag":94,"props":1068,"children":1069},{"style":137},[1070],{"type":37,"value":347},{"type":32,"tag":94,"props":1072,"children":1073},{"style":107},[1074],{"type":37,"value":245},{"type":32,"tag":94,"props":1076,"children":1077},{"style":137},[1078],{"type":37,"value":65},{"type":32,"tag":94,"props":1080,"children":1081},{"style":107},[1082],{"type":37,"value":155},{"type":32,"tag":94,"props":1084,"children":1085},{"style":101},[1086],{"type":37,"value":115},{"type":32,"tag":94,"props":1088,"children":1089},{"style":107},[1090],{"type":37,"value":368},{"type":32,"tag":94,"props":1092,"children":1093},{"class":96,"line":195},[1094,1098],{"type":32,"tag":94,"props":1095,"children":1096},{"style":101},[1097],{"type":37,"value":607},{"type":32,"tag":94,"props":1099,"children":1100},{"style":107},[1101],{"type":37,"value":1102}," cohort_assignments c\n",{"type":32,"tag":94,"props":1104,"children":1105},{"class":96,"line":204},[1106,1111,1115,1119,1123,1127,1131,1135,1139,1143],{"type":32,"tag":94,"props":1107,"children":1108},{"style":101},[1109],{"type":37,"value":1110},"JOIN",{"type":32,"tag":94,"props":1112,"children":1113},{"style":107},[1114],{"type":37,"value":395},{"type":32,"tag":94,"props":1116,"children":1117},{"style":101},[1118],{"type":37,"value":400},{"type":32,"tag":94,"props":1120,"children":1121},{"style":137},[1122],{"type":37,"value":405},{"type":32,"tag":94,"props":1124,"children":1125},{"style":107},[1126],{"type":37,"value":245},{"type":32,"tag":94,"props":1128,"children":1129},{"style":137},[1130],{"type":37,"value":65},{"type":32,"tag":94,"props":1132,"children":1133},{"style":101},[1134],{"type":37,"value":418},{"type":32,"tag":94,"props":1136,"children":1137},{"style":137},[1138],{"type":37,"value":347},{"type":32,"tag":94,"props":1140,"children":1141},{"style":107},[1142],{"type":37,"value":245},{"type":32,"tag":94,"props":1144,"children":1145},{"style":137},[1146],{"type":37,"value":431},{"type":32,"tag":94,"props":1148,"children":1149},{"class":96,"line":221},[1150,1154,1158,1162,1166,1171],{"type":32,"tag":94,"props":1151,"children":1152},{"style":101},[1153],{"type":37,"value":866},{"type":32,"tag":94,"props":1155,"children":1156},{"style":137},[1157],{"type":37,"value":405},{"type":32,"tag":94,"props":1159,"children":1160},{"style":107},[1161],{"type":37,"value":245},{"type":32,"tag":94,"props":1163,"children":1164},{"style":137},[1165],{"type":37,"value":250},{"type":32,"tag":94,"props":1167,"children":1168},{"style":101},[1169],{"type":37,"value":1170}," >=",{"type":32,"tag":94,"props":1172,"children":1173},{"style":879},[1174],{"type":37,"value":1175}," '2026-01-01'\n",{"type":32,"tag":94,"props":1177,"children":1178},{"class":96,"line":234},[1179,1183,1187,1191,1195],{"type":32,"tag":94,"props":1180,"children":1181},{"style":101},[1182],{"type":37,"value":890},{"type":32,"tag":94,"props":1184,"children":1185},{"style":137},[1186],{"type":37,"value":444},{"type":32,"tag":94,"props":1188,"children":1189},{"style":107},[1190],{"type":37,"value":67},{"type":32,"tag":94,"props":1192,"children":1193},{"style":137},[1194],{"type":37,"value":504},{"type":32,"tag":94,"props":1196,"children":1197},{"style":107},[1198],{"type":37,"value":509},{"type":32,"tag":33,"props":1200,"children":1201},{},[1202,1204,1209],{"type":37,"value":1203},"С partition pruning, если фильтруешь 4 недели когорт, сканирование составит 200 MB. JOIN все еще читает полную ",{"type":32,"tag":40,"props":1205,"children":1207},{"className":1206},[],[1208],{"type":37,"value":520},{"type":37,"value":1210},", но уже отфильтрованную до когорт, без лишних пользователей.",{"type":32,"tag":529,"props":1212,"children":1214},{"id":1213},"инкрементальное-обновление",[1215],{"type":37,"value":1216},"Инкрементальное обновление",{"type":32,"tag":33,"props":1218,"children":1219},{},[1220,1222,1228],{"type":37,"value":1221},"Таблица ",{"type":32,"tag":40,"props":1223,"children":1225},{"className":1224},[],[1226],{"type":37,"value":1227},"cohort_assignments",{"type":37,"value":1229}," обновляется каждый день, но не пересчитывается с нуля. Используй dbt incremental модель:",{"type":32,"tag":84,"props":1231,"children":1233},{"className":86,"code":1232,"language":88,"meta":16,"style":16},"{{\n  config(\n    materialized='incremental',\n    partition_by={'field': 'cohort_week', 'data_type': 'date'},\n    cluster_by=['user_id']\n  )\n}}\n\nSELECT \n  user_id,\n  DATE_TRUNC(MIN(event_time), WEEK) AS cohort_week,\n  MIN(event_time) AS first_seen_at\nFROM {{ ref('events') }}\n{% if is_incremental() %}\n  WHERE event_time > (SELECT MAX(first_seen_at) FROM {{ this }})\n{% endif %}\nGROUP BY user_id\n",[1234],{"type":32,"tag":40,"props":1235,"children":1236},{"__ignoreMap":16},[1237,1245,1253,1275,1330,1347,1355,1363,1372,1383,1390,1421,1440,1462,1480,1525,1534],{"type":32,"tag":94,"props":1238,"children":1239},{"class":96,"line":97},[1240],{"type":32,"tag":94,"props":1241,"children":1242},{"style":107},[1243],{"type":37,"value":1244},"{{\n",{"type":32,"tag":94,"props":1246,"children":1247},{"class":96,"line":123},[1248],{"type":32,"tag":94,"props":1249,"children":1250},{"style":107},[1251],{"type":37,"value":1252},"  config(\n",{"type":32,"tag":94,"props":1254,"children":1255},{"class":96,"line":167},[1256,1261,1266,1271],{"type":32,"tag":94,"props":1257,"children":1258},{"style":107},[1259],{"type":37,"value":1260},"    materialized",{"type":32,"tag":94,"props":1262,"children":1263},{"style":101},[1264],{"type":37,"value":1265},"=",{"type":32,"tag":94,"props":1267,"children":1268},{"style":879},[1269],{"type":37,"value":1270},"'incremental'",{"type":32,"tag":94,"props":1272,"children":1273},{"style":107},[1274],{"type":37,"value":255},{"type":32,"tag":94,"props":1276,"children":1277},{"class":96,"line":181},[1278,1283,1287,1292,1297,1302,1307,1311,1316,1320,1325],{"type":32,"tag":94,"props":1279,"children":1280},{"style":107},[1281],{"type":37,"value":1282},"    partition_by",{"type":32,"tag":94,"props":1284,"children":1285},{"style":101},[1286],{"type":37,"value":1265},{"type":32,"tag":94,"props":1288,"children":1289},{"style":107},[1290],{"type":37,"value":1291},"{",{"type":32,"tag":94,"props":1293,"children":1294},{"style":879},[1295],{"type":37,"value":1296},"'field'",{"type":32,"tag":94,"props":1298,"children":1299},{"style":107},[1300],{"type":37,"value":1301},": ",{"type":32,"tag":94,"props":1303,"children":1304},{"style":879},[1305],{"type":37,"value":1306},"'cohort_week'",{"type":32,"tag":94,"props":1308,"children":1309},{"style":107},[1310],{"type":37,"value":67},{"type":32,"tag":94,"props":1312,"children":1313},{"style":879},[1314],{"type":37,"value":1315},"'data_type'",{"type":32,"tag":94,"props":1317,"children":1318},{"style":107},[1319],{"type":37,"value":1301},{"type":32,"tag":94,"props":1321,"children":1322},{"style":879},[1323],{"type":37,"value":1324},"'date'",{"type":32,"tag":94,"props":1326,"children":1327},{"style":107},[1328],{"type":37,"value":1329},"},\n",{"type":32,"tag":94,"props":1331,"children":1332},{"class":96,"line":195},[1333,1338,1342],{"type":32,"tag":94,"props":1334,"children":1335},{"style":107},[1336],{"type":37,"value":1337},"    cluster_by",{"type":32,"tag":94,"props":1339,"children":1340},{"style":101},[1341],{"type":37,"value":1265},{"type":32,"tag":94,"props":1343,"children":1344},{"style":107},[1345],{"type":37,"value":1346},"['user_id']\n",{"type":32,"tag":94,"props":1348,"children":1349},{"class":96,"line":204},[1350],{"type":32,"tag":94,"props":1351,"children":1352},{"style":107},[1353],{"type":37,"value":1354},"  )\n",{"type":32,"tag":94,"props":1356,"children":1357},{"class":96,"line":221},[1358],{"type":32,"tag":94,"props":1359,"children":1360},{"style":107},[1361],{"type":37,"value":1362},"}}\n",{"type":32,"tag":94,"props":1364,"children":1365},{"class":96,"line":234},[1366],{"type":32,"tag":94,"props":1367,"children":1369},{"emptyLinePlaceholder":1368},true,[1370],{"type":37,"value":1371},"\n",{"type":32,"tag":94,"props":1373,"children":1374},{"class":96,"line":26},[1375,1379],{"type":32,"tag":94,"props":1376,"children":1377},{"style":101},[1378],{"type":37,"value":471},{"type":32,"tag":94,"props":1380,"children":1381},{"style":107},[1382],{"type":37,"value":231},{"type":32,"tag":94,"props":1384,"children":1385},{"class":96,"line":326},[1386],{"type":32,"tag":94,"props":1387,"children":1388},{"style":107},[1389],{"type":37,"value":792},{"type":32,"tag":94,"props":1391,"children":1392},{"class":96,"line":371},[1393,1397,1401,1405,1409,1413,1417],{"type":32,"tag":94,"props":1394,"children":1395},{"style":107},[1396],{"type":37,"value":800},{"type":32,"tag":94,"props":1398,"children":1399},{"style":137},[1400],{"type":37,"value":140},{"type":32,"tag":94,"props":1402,"children":1403},{"style":107},[1404],{"type":37,"value":145},{"type":32,"tag":94,"props":1406,"children":1407},{"style":101},[1408],{"type":37,"value":150},{"type":32,"tag":94,"props":1410,"children":1411},{"style":107},[1412],{"type":37,"value":155},{"type":32,"tag":94,"props":1414,"children":1415},{"style":101},[1416],{"type":37,"value":115},{"type":32,"tag":94,"props":1418,"children":1419},{"style":107},[1420],{"type":37,"value":825},{"type":32,"tag":94,"props":1422,"children":1423},{"class":96,"line":384},[1424,1428,1432,1436],{"type":32,"tag":94,"props":1425,"children":1426},{"style":137},[1427],{"type":37,"value":833},{"type":32,"tag":94,"props":1429,"children":1430},{"style":107},[1431],{"type":37,"value":838},{"type":32,"tag":94,"props":1433,"children":1434},{"style":101},[1435],{"type":37,"value":115},{"type":32,"tag":94,"props":1437,"children":1438},{"style":107},[1439],{"type":37,"value":847},{"type":32,"tag":94,"props":1441,"children":1442},{"class":96,"line":434},[1443,1447,1452,1457],{"type":32,"tag":94,"props":1444,"children":1445},{"style":101},[1446],{"type":37,"value":607},{"type":32,"tag":94,"props":1448,"children":1449},{"style":107},[1450],{"type":37,"value":1451}," {{ ref(",{"type":32,"tag":94,"props":1453,"children":1454},{"style":879},[1455],{"type":37,"value":1456},"'events'",{"type":32,"tag":94,"props":1458,"children":1459},{"style":107},[1460],{"type":37,"value":1461},") }}\n",{"type":32,"tag":94,"props":1463,"children":1464},{"class":96,"line":456},[1465,1470,1475],{"type":32,"tag":94,"props":1466,"children":1467},{"style":107},[1468],{"type":37,"value":1469},"{% ",{"type":32,"tag":94,"props":1471,"children":1472},{"style":101},[1473],{"type":37,"value":1474},"if",{"type":32,"tag":94,"props":1476,"children":1477},{"style":107},[1478],{"type":37,"value":1479}," is_incremental() %}\n",{"type":32,"tag":94,"props":1481,"children":1482},{"class":96,"line":465},[1483,1488,1492,1497,1502,1506,1511,1516,1520],{"type":32,"tag":94,"props":1484,"children":1485},{"style":101},[1486],{"type":37,"value":1487},"  WHERE",{"type":32,"tag":94,"props":1489,"children":1490},{"style":107},[1491],{"type":37,"value":871},{"type":32,"tag":94,"props":1493,"children":1494},{"style":101},[1495],{"type":37,"value":1496},">",{"type":32,"tag":94,"props":1498,"children":1499},{"style":107},[1500],{"type":37,"value":1501}," (",{"type":32,"tag":94,"props":1503,"children":1504},{"style":101},[1505],{"type":37,"value":471},{"type":32,"tag":94,"props":1507,"children":1508},{"style":137},[1509],{"type":37,"value":1510}," MAX",{"type":32,"tag":94,"props":1512,"children":1513},{"style":107},[1514],{"type":37,"value":1515},"(first_seen_at) ",{"type":32,"tag":94,"props":1517,"children":1518},{"style":101},[1519],{"type":37,"value":607},{"type":32,"tag":94,"props":1521,"children":1522},{"style":107},[1523],{"type":37,"value":1524}," {{ this }})\n",{"type":32,"tag":94,"props":1526,"children":1528},{"class":96,"line":1527},16,[1529],{"type":32,"tag":94,"props":1530,"children":1531},{"style":107},[1532],{"type":37,"value":1533},"{% endif %}\n",{"type":32,"tag":94,"props":1535,"children":1537},{"class":96,"line":1536},17,[1538,1542],{"type":32,"tag":94,"props":1539,"children":1540},{"style":101},[1541],{"type":37,"value":890},{"type":32,"tag":94,"props":1543,"children":1544},{"style":107},[1545],{"type":37,"value":192},{"type":32,"tag":33,"props":1547,"children":1548},{},[1549],{"type":37,"value":1550},"Первый запуск обрабатывает все данные, последующие добавляют только новых пользователей. Сканирование 500 GB вместо 2 GB в день.",{"type":32,"tag":49,"props":1552,"children":1554},{"id":1553},"агрегированная-таблица-удержания-pre-compute-метрик-на-уровне-недели",[1555],{"type":37,"value":1556},"Агрегированная таблица удержания: Pre-compute метрик на уровне недели",{"type":32,"tag":33,"props":1558,"children":1559},{},[1560,1562,1567],{"type":37,"value":1561},"Таблица назначения когорт ускорила запрос удержания, но дашборд все еще JOIN'ит ",{"type":32,"tag":40,"props":1563,"children":1565},{"className":1564},[],[1566],{"type":37,"value":520},{"type":37,"value":1568}," при каждом запросе. Один шаг дальше: pre-compute метрики удержания на недельной основе, храни в отдельной таблице.",{"type":32,"tag":84,"props":1570,"children":1572},{"className":86,"code":1571,"language":88,"meta":16,"style":16},"CREATE TABLE cohort_retention_weekly\nPARTITION BY cohort_week\nCLUSTER BY weeks_since_cohort\nAS\nSELECT \n  c.cohort_week,\n  DATE_DIFF(DATE_TRUNC(e.event_time, WEEK), c.cohort_week, WEEK) AS weeks_since_cohort,\n  COUNT(DISTINCT e.user_id) AS active_users,\n  COUNT(*) AS total_events,\n  APPROX_QUANTILES(session_duration, 100)[OFFSET(50)] AS median_session_duration\nFROM cohort_assignments c\nJOIN events e ON c.user_id = e.user_id\nGROUP BY 1, 2;\n",[1573],{"type":32,"tag":40,"props":1574,"children":1575},{"__ignoreMap":16},[1576,1592,1607,1623,1630,1641,1660,1723,1763,1792,1819,1830,1873],{"type":32,"tag":94,"props":1577,"children":1578},{"class":96,"line":97},[1579,1583,1587],{"type":32,"tag":94,"props":1580,"children":1581},{"style":101},[1582],{"type":37,"value":554},{"type":32,"tag":94,"props":1584,"children":1585},{"style":101},[1586],{"type":37,"value":726},{"type":32,"tag":94,"props":1588,"children":1589},{"style":729},[1590],{"type":37,"value":1591}," cohort_retention_weekly\n",{"type":32,"tag":94,"props":1593,"children":1594},{"class":96,"line":123},[1595,1599,1603],{"type":32,"tag":94,"props":1596,"children":1597},{"style":101},[1598],{"type":37,"value":740},{"type":32,"tag":94,"props":1600,"children":1601},{"style":101},[1602],{"type":37,"value":745},{"type":32,"tag":94,"props":1604,"children":1605},{"style":107},[1606],{"type":37,"value":164},{"type":32,"tag":94,"props":1608,"children":1609},{"class":96,"line":167},[1610,1614,1618],{"type":32,"tag":94,"props":1611,"children":1612},{"style":107},[1613],{"type":37,"value":757},{"type":32,"tag":94,"props":1615,"children":1616},{"style":101},[1617],{"type":37,"value":762},{"type":32,"tag":94,"props":1619,"children":1620},{"style":107},[1621],{"type":37,"value":1622}," weeks_since_cohort\n",{"type":32,"tag":94,"props":1624,"children":1625},{"class":96,"line":181},[1626],{"type":32,"tag":94,"props":1627,"children":1628},{"style":101},[1629],{"type":37,"value":564},{"type":32,"tag":94,"props":1631,"children":1632},{"class":96,"line":195},[1633,1637],{"type":32,"tag":94,"props":1634,"children":1635},{"style":101},[1636],{"type":37,"value":471},{"type":32,"tag":94,"props":1638,"children":1639},{"style":107},[1640],{"type":37,"value":231},{"type":32,"tag":94,"props":1642,"children":1643},{"class":96,"line":204},[1644,1648,1652,1656],{"type":32,"tag":94,"props":1645,"children":1646},{"style":137},[1647],{"type":37,"value":973},{"type":32,"tag":94,"props":1649,"children":1650},{"style":107},[1651],{"type":37,"value":245},{"type":32,"tag":94,"props":1653,"children":1654},{"style":137},[1655],{"type":37,"value":250},{"type":32,"tag":94,"props":1657,"children":1658},{"style":107},[1659],{"type":37,"value":255},{"type":32,"tag":94,"props":1661,"children":1662},{"class":96,"line":221},[1663,1667,1671,1675,1679,1683,1687,1691,1695,1699,1703,1707,1711,1715,1719],{"type":32,"tag":94,"props":1664,"children":1665},{"style":107},[1666],{"type":37,"value":993},{"type":32,"tag":94,"props":1668,"children":1669},{"style":137},[1670],{"type":37,"value":268},{"type":32,"tag":94,"props":1672,"children":1673},{"style":107},[1674],{"type":37,"value":245},{"type":32,"tag":94,"props":1676,"children":1677},{"style":137},[1678],{"type":37,"value":73},{"type":32,"tag":94,"props":1680,"children":1681},{"style":107},[1682],{"type":37,"value":67},{"type":32,"tag":94,"props":1684,"children":1685},{"style":101},[1686],{"type":37,"value":150},{"type":32,"tag":94,"props":1688,"children":1689},{"style":107},[1690],{"type":37,"value":289},{"type":32,"tag":94,"props":1692,"children":1693},{"style":137},[1694],{"type":37,"value":294},{"type":32,"tag":94,"props":1696,"children":1697},{"style":107},[1698],{"type":37,"value":245},{"type":32,"tag":94,"props":1700,"children":1701},{"style":137},[1702],{"type":37,"value":250},{"type":32,"tag":94,"props":1704,"children":1705},{"style":107},[1706],{"type":37,"value":67},{"type":32,"tag":94,"props":1708,"children":1709},{"style":101},[1710],{"type":37,"value":150},{"type":32,"tag":94,"props":1712,"children":1713},{"style":107},[1714],{"type":37,"value":155},{"type":32,"tag":94,"props":1716,"children":1717},{"style":101},[1718],{"type":37,"value":115},{"type":32,"tag":94,"props":1720,"children":1721},{"style":107},[1722],{"type":37,"value":323},{"type":32,"tag":94,"props":1724,"children":1725},{"class":96,"line":234},[1726,1730,1734,1738,1742,1746,1750,1754,1758],{"type":32,"tag":94,"props":1727,"children":1728},{"style":137},[1729],{"type":37,"value":1058},{"type":32,"tag":94,"props":1731,"children":1732},{"style":107},[1733],{"type":37,"value":337},{"type":32,"tag":94,"props":1735,"children":1736},{"style":101},[1737],{"type":37,"value":342},{"type":32,"tag":94,"props":1739,"children":1740},{"style":137},[1741],{"type":37,"value":347},{"type":32,"tag":94,"props":1743,"children":1744},{"style":107},[1745],{"type":37,"value":245},{"type":32,"tag":94,"props":1747,"children":1748},{"style":137},[1749],{"type":37,"value":65},{"type":32,"tag":94,"props":1751,"children":1752},{"style":107},[1753],{"type":37,"value":155},{"type":32,"tag":94,"props":1755,"children":1756},{"style":101},[1757],{"type":37,"value":115},{"type":32,"tag":94,"props":1759,"children":1760},{"style":107},[1761],{"type":37,"value":1762}," active_users,\n",{"type":32,"tag":94,"props":1764,"children":1765},{"class":96,"line":26},[1766,1770,1774,1779,1783,1787],{"type":32,"tag":94,"props":1767,"children":1768},{"style":137},[1769],{"type":37,"value":1058},{"type":32,"tag":94,"props":1771,"children":1772},{"style":107},[1773],{"type":37,"value":337},{"type":32,"tag":94,"props":1775,"children":1776},{"style":101},[1777],{"type":37,"value":1778},"*",{"type":32,"tag":94,"props":1780,"children":1781},{"style":107},[1782],{"type":37,"value":155},{"type":32,"tag":94,"props":1784,"children":1785},{"style":101},[1786],{"type":37,"value":115},{"type":32,"tag":94,"props":1788,"children":1789},{"style":107},[1790],{"type":37,"value":1791}," total_events,\n",{"type":32,"tag":94,"props":1793,"children":1794},{"class":96,"line":326},[1795,1800,1805,1810,1814],{"type":32,"tag":94,"props":1796,"children":1797},{"style":107},[1798],{"type":37,"value":1799},"  APPROX_QUANTILES(session_duration, ",{"type":32,"tag":94,"props":1801,"children":1802},{"style":137},[1803],{"type":37,"value":1804},"100",{"type":32,"tag":94,"props":1806,"children":1807},{"style":107},[1808],{"type":37,"value":1809},")[OFFSET(50)] ",{"type":32,"tag":94,"props":1811,"children":1812},{"style":101},[1813],{"type":37,"value":115},{"type":32,"tag":94,"props":1815,"children":1816},{"style":107},[1817],{"type":37,"value":1818}," median_session_duration\n",{"type":32,"tag":94,"props":1820,"children":1821},{"class":96,"line":371},[1822,1826],{"type":32,"tag":94,"props":1823,"children":1824},{"style":101},[1825],{"type":37,"value":607},{"type":32,"tag":94,"props":1827,"children":1828},{"style":107},[1829],{"type":37,"value":1102},{"type":32,"tag":94,"props":1831,"children":1832},{"class":96,"line":384},[1833,1837,1841,1845,1849,1853,1857,1861,1865,1869],{"type":32,"tag":94,"props":1834,"children":1835},{"style":101},[1836],{"type":37,"value":1110},{"type":32,"tag":94,"props":1838,"children":1839},{"style":107},[1840],{"type":37,"value":395},{"type":32,"tag":94,"props":1842,"children":1843},{"style":101},[1844],{"type":37,"value":400},{"type":32,"tag":94,"props":1846,"children":1847},{"style":137},[1848],{"type":37,"value":405},{"type":32,"tag":94,"props":1850,"children":1851},{"style":107},[1852],{"type":37,"value":245},{"type":32,"tag":94,"props":1854,"children":1855},{"style":137},[1856],{"type":37,"value":65},{"type":32,"tag":94,"props":1858,"children":1859},{"style":101},[1860],{"type":37,"value":418},{"type":32,"tag":94,"props":1862,"children":1863},{"style":137},[1864],{"type":37,"value":347},{"type":32,"tag":94,"props":1866,"children":1867},{"style":107},[1868],{"type":37,"value":245},{"type":32,"tag":94,"props":1870,"children":1871},{"style":137},[1872],{"type":37,"value":431},{"type":32,"tag":94,"props":1874,"children":1875},{"class":96,"line":434},[1876,1880,1884,1888,1892],{"type":32,"tag":94,"props":1877,"children":1878},{"style":101},[1879],{"type":37,"value":890},{"type":32,"tag":94,"props":1881,"children":1882},{"style":137},[1883],{"type":37,"value":444},{"type":32,"tag":94,"props":1885,"children":1886},{"style":107},[1887],{"type":37,"value":67},{"type":32,"tag":94,"props":1889,"children":1890},{"style":137},[1891],{"type":37,"value":504},{"type":32,"tag":94,"props":1893,"children":1894},{"style":107},[1895],{"type":37,"value":509},{"type":32,"tag":33,"props":1897,"children":1898},{},[1899],{"type":37,"value":900},{"type":32,"tag":902,"props":1901,"children":1902},{},[1903,1912,1936],{"type":32,"tag":648,"props":1904,"children":1905},{},[1906,1910],{"type":32,"tag":652,"props":1907,"children":1908},{},[1909],{"type":37,"value":940},{"type":37,"value":1911}," 52 недели × 52 недели_с_начала_когорты × 3 метрики = ~8.100 строк (для года данных). Килобайты.",{"type":32,"tag":648,"props":1913,"children":1914},{},[1915,1920,1922,1928,1929,1934],{"type":32,"tag":652,"props":1916,"children":1917},{},[1918],{"type":37,"value":1919},"Сканирование:",{"type":37,"value":1921}," Дашборд читает ",{"type":32,"tag":40,"props":1923,"children":1925},{"className":1924},[],[1926],{"type":37,"value":1927},"cohort_retention_weekly",{"type":37,"value":67},{"type":32,"tag":40,"props":1930,"children":1932},{"className":1931},[],[1933],{"type":37,"value":520},{"type":37,"value":1935}," не трогает. Сканирование \u003C 1 MB.",{"type":32,"tag":648,"props":1937,"children":1938},{},[1939,1944],{"type":32,"tag":652,"props":1940,"children":1941},{},[1942],{"type":37,"value":1943},"Задержка:",{"type":37,"value":1945}," BigQuery читает 1 MB за 80 ms. Дашборд теперь sub-second.",{"type":32,"tag":33,"props":1947,"children":1948},{},[1949,1951,1957],{"type":37,"value":1950},"Компромисс: эту таблицу нужно обновлять один раз в день. Если требуются свежие данные, refresh раз в час (dbt schedule ",{"type":32,"tag":40,"props":1952,"children":1954},{"className":1953},[],[1955],{"type":37,"value":1956},"0 * * * *",{"type":37,"value":1958},"). Стоимость refresh'а: JOIN cohort_assignments + events, ~10 GB сканирования. 24× в день = 240 GB, месяц = 7.2 TB. Сравнение: если бы дашборд запускал 1.000 когортных запросов без агрегирования, было бы 8 TB сканирования. Агрегированная таблица снизила сканирование на 10%, задержку с 20 секунд до 80 ms.",{"type":32,"tag":529,"props":1960,"children":1962},{"id":1961},"стратегия-partitioning-cohort_week-vs-event_week",[1963],{"type":37,"value":1964},"Стратегия Partitioning: cohort_week vs event_week",{"type":32,"tag":33,"props":1966,"children":1967},{},[1968,1970,1975,1977,1982,1984,1990],{"type":37,"value":1969},"Таблицу ",{"type":32,"tag":40,"props":1971,"children":1973},{"className":1972},[],[1974],{"type":37,"value":633},{"type":37,"value":1976}," партиционировать по ",{"type":32,"tag":40,"props":1978,"children":1980},{"className":1979},[],[1981],{"type":37,"value":250},{"type":37,"value":1983}," или по ",{"type":32,"tag":40,"props":1985,"children":1987},{"className":1986},[],[1988],{"type":37,"value":1989},"event_week",{"type":37,"value":1991},"? Есть два подхода:",{"type":32,"tag":33,"props":1993,"children":1994},{},[1995],{"type":32,"tag":652,"props":1996,"children":1997},{},[1998],{"type":37,"value":1999},"Partition by cohort_week:",{"type":32,"tag":902,"props":2001,"children":2002},{},[2003,2008,2021],{"type":32,"tag":648,"props":2004,"children":2005},{},[2006],{"type":37,"value":2007},"Использование: \"Какая кривая удержания у когорты 2026-W03?\"",{"type":32,"tag":648,"props":2009,"children":2010},{},[2011,2013,2019],{"type":37,"value":2012},"Pruning: ",{"type":32,"tag":40,"props":2014,"children":2016},{"className":2015},[],[2017],{"type":37,"value":2018},"WHERE cohort_week = '2026-01-13'",{"type":37,"value":2020}," → одна партиция читается",{"type":32,"tag":648,"props":2022,"children":2023},{},[2024],{"type":37,"value":2025},"Сложность: Если дашборд спрашивает \"общее удержание последних 4 недель\", читаются 4 партиции. Но большинство запросов удержания — когортные, этот подход оптимален.",{"type":32,"tag":33,"props":2027,"children":2028},{},[2029],{"type":32,"tag":652,"props":2030,"children":2031},{},[2032],{"type":37,"value":2033},"Partition by event_week:",{"type":32,"tag":902,"props":2035,"children":2036},{},[2037,2042,2054],{"type":32,"tag":648,"props":2038,"children":2039},{},[2040],{"type":37,"value":2041},"Использование: \"Какие когорты активны на этой неделе?\"",{"type":32,"tag":648,"props":2043,"children":2044},{},[2045,2046,2052],{"type":37,"value":2012},{"type":32,"tag":40,"props":2047,"children":2049},{"className":2048},[],[2050],{"type":37,"value":2051},"WHERE event_week = '2026-07-21'",{"type":37,"value":2053}," → одна партиция",{"type":32,"tag":648,"props":2055,"children":2056},{},[2057],{"type":37,"value":2058},"Сложность: Добавь фильтр когорты, partition pruning не работает, читаются все партиции.",{"type":32,"tag":33,"props":2060,"children":2061},{},[2062,2064,2073],{"type":37,"value":2063},"В проектах Roibase по ",{"type":32,"tag":2065,"props":2066,"children":2070},"a",{"href":2067,"rel":2068},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Fverianalizi",[2069],"nofollow",[2071],{"type":37,"value":2072},"анализу данных",{"type":37,"value":2074}," таблица удержания партиционируется по cohort_week, потому что 80% запросов удержания — в формате \"когорта X, неделя N\".",{"type":32,"tag":49,"props":2076,"children":2078},{"id":2077},"оптимизация-стоимости-запросов-clustering-и-bi-engine",[2079],{"type":37,"value":2080},"Оптимизация стоимости запросов: Clustering и BI Engine",{"type":32,"tag":33,"props":2082,"children":2083},{},[2084],{"type":37,"value":2085},"Partition pruning сверху вниз (какие блоки файлов читать), clustering слева направо (какие строки в блоке читать). Вместе они минимизируют сканирование.",{"type":32,"tag":84,"props":2087,"children":2089},{"className":86,"code":2088,"language":88,"meta":16,"style":16},"CREATE TABLE cohort_retention_weekly\nPARTITION BY cohort_week\nCLUSTER BY weeks_since_cohort, platform, country;\n",[2090],{"type":32,"tag":40,"props":2091,"children":2092},{"__ignoreMap":16},[2093,2108,2123],{"type":32,"tag":94,"props":2094,"children":2095},{"class":96,"line":97},[2096,2100,2104],{"type":32,"tag":94,"props":2097,"children":2098},{"style":101},[2099],{"type":37,"value":554},{"type":32,"tag":94,"props":2101,"children":2102},{"style":101},[2103],{"type":37,"value":726},{"type":32,"tag":94,"props":2105,"children":2106},{"style":729},[2107],{"type":37,"value":1591},{"type":32,"tag":94,"props":2109,"children":2110},{"class":96,"line":123},[2111,2115,2119],{"type":32,"tag":94,"props":2112,"children":2113},{"style":101},[2114],{"type":37,"value":740},{"type":32,"tag":94,"props":2116,"children":2117},{"style":101},[2118],{"type":37,"value":745},{"type":32,"tag":94,"props":2120,"children":2121},{"style":107},[2122],{"type":37,"value":164},{"type":32,"tag":94,"props":2124,"children":2125},{"class":96,"line":167},[2126,2130,2134],{"type":32,"tag":94,"props":2127,"children":2128},{"style":107},[2129],{"type":37,"value":757},{"type":32,"tag":94,"props":2131,"children":2132},{"style":101},[2133],{"type":37,"value":762},{"type":32,"tag":94,"props":2135,"children":2136},{"style":107},[2137],{"type":37,"value":2138}," weeks_since_cohort, platform, country;\n",{"type":32,"tag":33,"props":2140,"children":2141},{},[2142,2144,2150],{"type":37,"value":2143},"Запрос ",{"type":32,"tag":40,"props":2145,"children":2147},{"className":2146},[],[2148],{"type":37,"value":2149},"WHERE weeks_since_cohort = 4 AND platform = 'iOS'",{"type":37,"value":2151},":",{"type":32,"tag":644,"props":2153,"children":2154},{},[2155,2160],{"type":32,"tag":648,"props":2156,"children":2157},{},[2158],{"type":37,"value":2159},"Partition pruning → только релевантные cohort_week партиции",{"type":32,"tag":648,"props":2161,"children":2162},{},[2163,2165,2171,2173],{"type":37,"value":2164},"Clustering → в партиции сначала строки ",{"type":32,"tag":40,"props":2166,"children":2168},{"className":2167},[],[2169],{"type":37,"value":2170},"weeks_since_cohort = 4",{"type":37,"value":2172},", потом ",{"type":32,"tag":40,"props":2174,"children":2176},{"className":2175},[],[2177],{"type":37,"value":2178},"platform = 'iOS'",{"type":32,"tag":33,"props":2180,"children":2181},{},[2182],{"type":37,"value":2183},"BigQuery принимает максимум 4 колонки для clustering. Порядок важен: самую часто фильтруемую колонку поставь первой.",{"type":32,"tag":33,"props":2185,"children":2186},{},[2187,2192,2194,2199],{"type":32,"tag":652,"props":2188,"children":2189},{},[2190],{"type":37,"value":2191},"BI Engine:",{"type":37,"value":2193}," In-memory кеш BigQuery. Если зарезервировать 100 GB BI Engine, часто используемые таблицы хранятся в RAM. Таблица ",{"type":32,"tag":40,"props":2195,"children":2197},{"className":2196},[],[2198],{"type":37,"value":1927},{"type":37,"value":2200}," весит 50 MB, полностью уместится в BI Engine, сканирование = 0 (cache hit). Стоимость: 100 GB × $100\u002Fмесяц = $100. Окупаемость: 10 TB экономии сканирования\u002Fмесяц = $62.50 сэкономлено. ROI положителен.",{"type":32,"tag":529,"props":2202,"children":2204},{"id":2203},"approximation-functions-метрики-без-точности-до-100",[2205],{"type":37,"value":2206},"Approximation Functions: метрики без точности до 100%",{"type":32,"tag":33,"props":2208,"children":2209},{},[2210,2212,2218],{"type":37,"value":2211},"В расчете удержания когорт некоторые метрики должны быть точные (",{"type":32,"tag":40,"props":2213,"children":2215},{"className":2214},[],[2216],{"type":37,"value":2217},"COUNT(DISTINCT user_id)",{"type":37,"value":2219},"), некоторые могут быть приблизительные (медиана длительности сеанса, перцентили).",{"type":32,"tag":33,"props":2221,"children":2222},{},[2223],{"type":37,"value":2224},"Approximate функции BigQuery:",{"type":32,"tag":902,"props":2226,"children":2227},{},[2228,2239,2250],{"type":32,"tag":648,"props":2229,"children":2230},{},[2231,2237],{"type":32,"tag":40,"props":2232,"children":2234},{"className":2233},[],[2235],{"type":37,"value":2236},"APPROX_COUNT_DISTINCT(user_id)",{"type":37,"value":2238}," → погрешность 2%, в 10× быстрее",{"type":32,"tag":648,"props":2240,"children":2241},{},[2242,2248],{"type":32,"tag":40,"props":2243,"children":2245},{"className":2244},[],[2246],{"type":37,"value":2247},"APPROX_QUANTILES(value, 100)[OFFSET(50)]",{"type":37,"value":2249}," → медиана, погрешность 1%",{"type":32,"tag":648,"props":2251,"children":2252},{},[2253,2259],{"type":32,"tag":40,"props":2254,"children":2256},{"className":2255},[],[2257],{"type":37,"value":2258},"APPROX_TOP_COUNT(event_name, 10)",{"type":37,"value":2260}," → топ-10 событий",{"type":32,"tag":33,"props":2262,"children":2263},{},[2264,2266,2272,2274,2280],{"type":37,"value":2265},"Пример: для 50M пользователей exact ",{"type":32,"tag":40,"props":2267,"children":2269},{"className":2268},[],[2270],{"type":37,"value":2271},"COUNT(DISTINCT ...)",{"type":37,"value":2273}," занимает 8 секунд, ",{"type":32,"tag":40,"props":2275,"children":2277},{"className":2276},[],[2278],{"type":37,"value":2279},"APPROX_COUNT_DISTINCT",{"type":37,"value":2281}," — 800 ms. На дашборде с real-time фильтрами используй approximate, в финальном отчете — exact.",{"type":32,"tag":49,"props":2283,"children":2285},{"id":2284},"incremental-update-strategy-event-time-vs-processing-time",[2286],{"type":37,"value":2287},"Incremental Update Strategy: event-time vs processing-time",{"type":32,"tag":33,"props":2289,"children":2290},{},[2291],{"type":37,"value":2292},"Таблица когорт обновляется раз в день, но какие события обрабатывать? Есть два timestamp'а:",{"type":32,"tag":644,"props":2294,"children":2295},{},[2296,2306],{"type":32,"tag":648,"props":2297,"children":2298},{},[2299,2304],{"type":32,"tag":652,"props":2300,"children":2301},{},[2302],{"type":37,"value":2303},"event_time:",{"type":37,"value":2305}," время события пользователя (client-side)",{"type":32,"tag":648,"props":2307,"children":2308},{},[2309,2314],{"type":32,"tag":652,"props":2310,"children":2311},{},[2312],{"type":37,"value":2313},"_PARTITIONTIME:",{"type":37,"value":2315}," время, когда BigQuery сохранил событие (server-side)",{"type":32,"tag":33,"props":2317,"children":2318},{},[2319,2321,2326],{"type":37,"value":2320},"Incremental update по ",{"type":32,"tag":40,"props":2322,"children":2324},{"className":2323},[],[2325],{"type":37,"value":73},{"type":37,"value":2151},{"type":32,"tag":84,"props":2328,"children":2330},{"className":86,"code":2329,"language":88,"meta":16,"style":16},"WHERE event_time > (SELECT MAX(event_time) FROM cohort_assignments)\n",[2331],{"type":32,"tag":40,"props":2332,"children":2333},{"__ignoreMap":16},[2334],{"type":32,"tag":94,"props":2335,"children":2336},{"class":96,"line":97},[2337,2341,2345,2349,2353,2357,2361,2365,2369],{"type":32,"tag":94,"props":2338,"children":2339},{"style":101},[2340],{"type":37,"value":866},{"type":32,"tag":94,"props":2342,"children":2343},{"style":107},[2344],{"type":37,"value":871},{"type":32,"tag":94,"props":2346,"children":2347},{"style":101},[2348],{"type":37,"value":1496},{"type":32,"tag":94,"props":2350,"children":2351},{"style":107},[2352],{"type":37,"value":1501},{"type":32,"tag":94,"props":2354,"children":2355},{"style":101},[2356],{"type":37,"value":471},{"type":32,"tag":94,"props":2358,"children":2359},{"style":137},[2360],{"type":37,"value":1510},{"type":32,"tag":94,"props":2362,"children":2363},{"style":107},[2364],{"type":37,"value":838},{"type":32,"tag":94,"props":2366,"children":2367},{"style":101},[2368],{"type":37,"value":607},{"type":32,"tag":94,"props":2370,"children":2371},{"style":107},[2372],{"type":37,"value":2373}," cohort_assignments)\n",{"type":32,"tag":33,"props":2375,"children":2376},{},[2377,2382,2384,2389],{"type":32,"tag":652,"props":2378,"children":2379},{},[2380],{"type":37,"value":2381},"Проблема:",{"type":37,"value":2383}," Late-arriving events. Пользователь был offline 3 дня, событие пришло batch'ом. Если ",{"type":32,"tag":40,"props":2385,"children":2387},{"className":2386},[],[2388],{"type":37,"value":73},{"type":37,"value":2390}," 3 дня назад, incremental запрос его пропустит.",{"type":32,"tag":33,"props":2392,"children":2393},{},[2394,2395,2401],{"type":37,"value":2320},{"type":32,"tag":40,"props":2396,"children":2398},{"className":2397},[],[2399],{"type":37,"value":2400},"_PARTITIONTIME",{"type":37,"value":2151},{"type":32,"tag":84,"props":2403,"children":2405},{"className":86,"code":2404,"language":88,"meta":16,"style":16},"WHERE _PARTITIONTIME > CURRENT_DATE() - 7\n",[2406],{"type":32,"tag":40,"props":2407,"children":2408},{"__ignoreMap":16},[2409],{"type":32,"tag":94,"props":2410,"children":2411},{"class":96,"line":97},[2412,2416,2421,2425,2430,2435],{"type":32,"tag":94,"props":2413,"children":2414},{"style":101},[2415],{"type":37,"value":866},{"type":32,"tag":94,"props":2417,"children":2418},{"style":107},[2419],{"type":37,"value":2420}," _PARTITIONTIME ",{"type":32,"tag":94,"props":2422,"children":2423},{"style":101},[2424],{"type":37,"value":1496},{"type":32,"tag":94,"props":2426,"children":2427},{"style":107},[2428],{"type":37,"value":2429}," CURRENT_DATE() ",{"type":32,"tag":94,"props":2431,"children":2432},{"style":101},[2433],{"type":37,"value":2434},"-",{"type":32,"tag":94,"props":2436,"children":2437},{"style":137},[2438],{"type":37,"value":2439}," 7\n",{"type":32,"tag":33,"props":2441,"children":2442},{},[2443,2448,2450,2455],{"type":32,"tag":652,"props":2444,"children":2445},{},[2446],{"type":37,"value":2447},"Преимущество:",{"type":37,"value":2449}," Переобрабатываешь последние 7 дней, late events ловятся.\n",{"type":32,"tag":652,"props":2451,"children":2452},{},[2453],{"type":37,"value":2454},"Стоимость:",{"type":37,"value":2456}," 7 дней events = ~14 GB сканирования в день (вместо 2 GB).",{"type":32,"tag":33,"props":2458,"children":2459},{},[2460,2462,2467],{"type":37,"value":2461},"Компромисс: если late events \u003C 1%, используй ",{"type":32,"tag":40,"props":2463,"children":2465},{"className":2464},[],[2466],{"type":37,"value":73},{"type":37,"value":2468},", сканирование ниже.",{"type":32,"tag":2470,"props":2471,"children":2472},"style",{},[2473],{"type":37,"value":2474},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":167,"depth":167,"links":2476},[2477,2480,2483,2486,2489],{"id":51,"depth":123,"text":54,"children":2478},[2479],{"id":531,"depth":167,"text":534},{"id":684,"depth":123,"text":687,"children":2481},[2482],{"id":1213,"depth":167,"text":1216},{"id":1553,"depth":123,"text":1556,"children":2484},[2485],{"id":1961,"depth":167,"text":1964},{"id":2077,"depth":123,"text":2080,"children":2487},[2488],{"id":2203,"depth":167,"text":2206},{"id":2284,"depth":123,"text":2287},"markdown","content:ru:data:cohort-table-architecture-scaling-retention.md","content","ru\u002Fdata\u002Fcohort-table-architecture-scaling-retention.md","ru\u002Fdata\u002Fcohort-table-architecture-scaling-retention","md",1785967486010]