[{"data":1,"prerenderedAt":3153},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fru\u002Fdata\u002Fcohort-tablitsa-arkhitektura-masshtabirovanie-analiza-uderzhaniia-v-produkcii":13},{"i18nKey":4,"paths":5},"data-007-2026-06",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fcohort-table-architecture-production-scaling","\u002Fen\u002Fdata\u002Fcohort-table-architecture-scaling-retention-analysis-production","\u002Fes\u002Fdata\u002Farquitectura-tabla-cohort","\u002Ffr\u002Fdata\u002Fcohort-table-architecture-production-scaling","\u002Fit\u002Fdata\u002Farchitettura-tabella-cohort","\u002Fru\u002Fdata\u002Fcohort-tablitsa-arkhitektura-masshtabirovanie-analiza-uderzhaniia-v-produkcii","\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":20,"i18nKey":4,"tags":21,"readingTime":27,"author":28,"body":29,"_type":3147,"_id":3148,"_source":3149,"_file":3150,"_stem":3151,"_extension":3152},"data",false,"","Архитектура таблицы когорт: масштабирование анализа удержания в production","Materialized views, partitioning и оптимизация стоимости запросов: обработка 100M+ событий в день в таблицах когорт за 5 секунд.","2026-06-09","verianalizi",[22,23,24,25,26],"cohort-analizi","bigquery","materialized-views","query-optimizacija","retention-engineering",9,"Roibase",{"type":30,"children":31,"toc":3138},"root",[32,40,47,83,452,471,478,491,1283,1288,1294,1306,1695,1700,1708,1834,1852,1858,1863,1881,1978,2003,2023,2047,2053,2090,2668,2673,2679,2692,3008,3021,3029,3127,3132],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Когда вы переносите метрики удержания в real-time dashboard, первый шок приходит в стоимость запросов. Базовый запрос когорты — «сколько пользователей, зарегистрированных 1 января, активны на день 7?» — при наивной написании JOIN сканирует 200GB данных, работает 18 секунд и генерирует счёт в 4 доллара. Для команды с 500 просмотрами dashboard в день это превращается в 60.000 долларов в месяц. Проблема не в вашей аналитической способности, а в архитектуре таблиц. Чтобы перенести когортный анализ в production, нужно хранить не данные событий, а снимки когорт.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"naive-cohort-query-почему-это-не-масштабируется",[45],{"type":38,"value":46},"Naive Cohort Query: почему это не масштабируется",{"type":33,"tag":34,"props":48,"children":49},{},[50,52,59,61,67,68,74,76,81],{"type":38,"value":51},"Классический запрос когорты объединяет три таблицы: ",{"type":33,"tag":53,"props":54,"children":56},"code",{"className":55},[],[57],{"type":38,"value":58},"users",{"type":38,"value":60},", ",{"type":33,"tag":53,"props":62,"children":64},{"className":63},[],[65],{"type":38,"value":66},"events",{"type":38,"value":60},{"type":33,"tag":53,"props":69,"children":71},{"className":70},[],[72],{"type":38,"value":73},"cohort_definitions",{"type":38,"value":75},". Каждый запрос сканирует таблицу ",{"type":33,"tag":53,"props":77,"children":79},{"className":78},[],[80],{"type":38,"value":66},{"type":38,"value":82}," полностью, без фильтра по partition. При 100M событий в день этот подход становится неустойчивым.",{"type":33,"tag":84,"props":85,"children":89},"pre",{"className":86,"code":87,"language":88,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","-- ❌ Anti-pattern: сканирование всех events при каждом запросе\nSELECT \n  DATE_TRUNC(u.created_at, DAY) AS cohort_date,\n  DATE_DIFF(e.event_date, u.created_at, DAY) AS day_n,\n  COUNT(DISTINCT u.user_id) AS retained_users\nFROM users u\nJOIN events e ON u.user_id = e.user_id\nWHERE u.created_at >= '2026-01-01'\n  AND e.event_name = 'session_start'\nGROUP BY 1, 2\nORDER BY 1, 2;\n","sql",[90],{"type":33,"tag":53,"props":91,"children":92},{"__ignoreMap":16},[93,105,121,170,230,276,290,340,372,402,425],{"type":33,"tag":94,"props":95,"children":98},"span",{"class":96,"line":97},"line",1,[99],{"type":33,"tag":94,"props":100,"children":102},{"style":101},"--shiki-default:#6A737D",[103],{"type":38,"value":104},"-- ❌ Anti-pattern: сканирование всех events при каждом запросе\n",{"type":33,"tag":94,"props":106,"children":108},{"class":96,"line":107},2,[109,115],{"type":33,"tag":94,"props":110,"children":112},{"style":111},"--shiki-default:#F97583",[113],{"type":38,"value":114},"SELECT",{"type":33,"tag":94,"props":116,"children":118},{"style":117},"--shiki-default:#E1E4E8",[119],{"type":38,"value":120}," \n",{"type":33,"tag":94,"props":122,"children":124},{"class":96,"line":123},3,[125,130,136,141,146,150,155,160,165],{"type":33,"tag":94,"props":126,"children":127},{"style":117},[128],{"type":38,"value":129},"  DATE_TRUNC(",{"type":33,"tag":94,"props":131,"children":133},{"style":132},"--shiki-default:#79B8FF",[134],{"type":38,"value":135},"u",{"type":33,"tag":94,"props":137,"children":138},{"style":117},[139],{"type":38,"value":140},".",{"type":33,"tag":94,"props":142,"children":143},{"style":132},[144],{"type":38,"value":145},"created_at",{"type":33,"tag":94,"props":147,"children":148},{"style":117},[149],{"type":38,"value":60},{"type":33,"tag":94,"props":151,"children":152},{"style":111},[153],{"type":38,"value":154},"DAY",{"type":33,"tag":94,"props":156,"children":157},{"style":117},[158],{"type":38,"value":159},") ",{"type":33,"tag":94,"props":161,"children":162},{"style":111},[163],{"type":38,"value":164},"AS",{"type":33,"tag":94,"props":166,"children":167},{"style":117},[168],{"type":38,"value":169}," cohort_date,\n",{"type":33,"tag":94,"props":171,"children":173},{"class":96,"line":172},4,[174,179,184,188,193,197,201,205,209,213,217,221,225],{"type":33,"tag":94,"props":175,"children":176},{"style":117},[177],{"type":38,"value":178},"  DATE_DIFF(",{"type":33,"tag":94,"props":180,"children":181},{"style":132},[182],{"type":38,"value":183},"e",{"type":33,"tag":94,"props":185,"children":186},{"style":117},[187],{"type":38,"value":140},{"type":33,"tag":94,"props":189,"children":190},{"style":132},[191],{"type":38,"value":192},"event_date",{"type":33,"tag":94,"props":194,"children":195},{"style":117},[196],{"type":38,"value":60},{"type":33,"tag":94,"props":198,"children":199},{"style":132},[200],{"type":38,"value":135},{"type":33,"tag":94,"props":202,"children":203},{"style":117},[204],{"type":38,"value":140},{"type":33,"tag":94,"props":206,"children":207},{"style":132},[208],{"type":38,"value":145},{"type":33,"tag":94,"props":210,"children":211},{"style":117},[212],{"type":38,"value":60},{"type":33,"tag":94,"props":214,"children":215},{"style":111},[216],{"type":38,"value":154},{"type":33,"tag":94,"props":218,"children":219},{"style":117},[220],{"type":38,"value":159},{"type":33,"tag":94,"props":222,"children":223},{"style":111},[224],{"type":38,"value":164},{"type":33,"tag":94,"props":226,"children":227},{"style":117},[228],{"type":38,"value":229}," day_n,\n",{"type":33,"tag":94,"props":231,"children":233},{"class":96,"line":232},5,[234,239,244,249,254,258,263,267,271],{"type":33,"tag":94,"props":235,"children":236},{"style":132},[237],{"type":38,"value":238},"  COUNT",{"type":33,"tag":94,"props":240,"children":241},{"style":117},[242],{"type":38,"value":243},"(",{"type":33,"tag":94,"props":245,"children":246},{"style":111},[247],{"type":38,"value":248},"DISTINCT",{"type":33,"tag":94,"props":250,"children":251},{"style":132},[252],{"type":38,"value":253}," u",{"type":33,"tag":94,"props":255,"children":256},{"style":117},[257],{"type":38,"value":140},{"type":33,"tag":94,"props":259,"children":260},{"style":132},[261],{"type":38,"value":262},"user_id",{"type":33,"tag":94,"props":264,"children":265},{"style":117},[266],{"type":38,"value":159},{"type":33,"tag":94,"props":268,"children":269},{"style":111},[270],{"type":38,"value":164},{"type":33,"tag":94,"props":272,"children":273},{"style":117},[274],{"type":38,"value":275}," retained_users\n",{"type":33,"tag":94,"props":277,"children":279},{"class":96,"line":278},6,[280,285],{"type":33,"tag":94,"props":281,"children":282},{"style":111},[283],{"type":38,"value":284},"FROM",{"type":33,"tag":94,"props":286,"children":287},{"style":117},[288],{"type":38,"value":289}," users u\n",{"type":33,"tag":94,"props":291,"children":293},{"class":96,"line":292},7,[294,299,304,309,313,317,321,326,331,335],{"type":33,"tag":94,"props":295,"children":296},{"style":111},[297],{"type":38,"value":298},"JOIN",{"type":33,"tag":94,"props":300,"children":301},{"style":117},[302],{"type":38,"value":303}," events e ",{"type":33,"tag":94,"props":305,"children":306},{"style":111},[307],{"type":38,"value":308},"ON",{"type":33,"tag":94,"props":310,"children":311},{"style":132},[312],{"type":38,"value":253},{"type":33,"tag":94,"props":314,"children":315},{"style":117},[316],{"type":38,"value":140},{"type":33,"tag":94,"props":318,"children":319},{"style":132},[320],{"type":38,"value":262},{"type":33,"tag":94,"props":322,"children":323},{"style":111},[324],{"type":38,"value":325}," =",{"type":33,"tag":94,"props":327,"children":328},{"style":132},[329],{"type":38,"value":330}," e",{"type":33,"tag":94,"props":332,"children":333},{"style":117},[334],{"type":38,"value":140},{"type":33,"tag":94,"props":336,"children":337},{"style":132},[338],{"type":38,"value":339},"user_id\n",{"type":33,"tag":94,"props":341,"children":343},{"class":96,"line":342},8,[344,349,353,357,361,366],{"type":33,"tag":94,"props":345,"children":346},{"style":111},[347],{"type":38,"value":348},"WHERE",{"type":33,"tag":94,"props":350,"children":351},{"style":132},[352],{"type":38,"value":253},{"type":33,"tag":94,"props":354,"children":355},{"style":117},[356],{"type":38,"value":140},{"type":33,"tag":94,"props":358,"children":359},{"style":132},[360],{"type":38,"value":145},{"type":33,"tag":94,"props":362,"children":363},{"style":111},[364],{"type":38,"value":365}," >=",{"type":33,"tag":94,"props":367,"children":369},{"style":368},"--shiki-default:#9ECBFF",[370],{"type":38,"value":371}," '2026-01-01'\n",{"type":33,"tag":94,"props":373,"children":374},{"class":96,"line":27},[375,380,384,388,393,397],{"type":33,"tag":94,"props":376,"children":377},{"style":111},[378],{"type":38,"value":379},"  AND",{"type":33,"tag":94,"props":381,"children":382},{"style":132},[383],{"type":38,"value":330},{"type":33,"tag":94,"props":385,"children":386},{"style":117},[387],{"type":38,"value":140},{"type":33,"tag":94,"props":389,"children":390},{"style":132},[391],{"type":38,"value":392},"event_name",{"type":33,"tag":94,"props":394,"children":395},{"style":111},[396],{"type":38,"value":325},{"type":33,"tag":94,"props":398,"children":399},{"style":368},[400],{"type":38,"value":401}," 'session_start'\n",{"type":33,"tag":94,"props":403,"children":405},{"class":96,"line":404},10,[406,411,416,420],{"type":33,"tag":94,"props":407,"children":408},{"style":111},[409],{"type":38,"value":410},"GROUP BY",{"type":33,"tag":94,"props":412,"children":413},{"style":132},[414],{"type":38,"value":415}," 1",{"type":33,"tag":94,"props":417,"children":418},{"style":117},[419],{"type":38,"value":60},{"type":33,"tag":94,"props":421,"children":422},{"style":132},[423],{"type":38,"value":424},"2\n",{"type":33,"tag":94,"props":426,"children":428},{"class":96,"line":427},11,[429,434,438,442,447],{"type":33,"tag":94,"props":430,"children":431},{"style":111},[432],{"type":38,"value":433},"ORDER BY",{"type":33,"tag":94,"props":435,"children":436},{"style":132},[437],{"type":38,"value":415},{"type":33,"tag":94,"props":439,"children":440},{"style":117},[441],{"type":38,"value":60},{"type":33,"tag":94,"props":443,"children":444},{"style":132},[445],{"type":38,"value":446},"2",{"type":33,"tag":94,"props":448,"children":449},{"style":117},[450],{"type":38,"value":451},";\n",{"type":33,"tag":34,"props":453,"children":454},{},[455,457,463,465,470],{"type":38,"value":456},"Этот запрос сканирует 480GB данных за 6 месяцев. На BigQuery это занимает 12 секунд из-за использования slots, стоит 2,40 доллара (on-demand pricing: 5$\u002FTB). Если вы умножите одну когорту на 20 разных метрик (доход, количество сессий, коэффициент конверсии), стоимость вырастет до 48 долларов. Если dashboard обновляется 100 раз в день, ежемесячная стоимость достигает 144.000 долларов. Чтобы адаптировать решение для масштабируемого production, существуют две стратегии: ",{"type":33,"tag":458,"props":459,"children":460},"strong",{},[461],{"type":38,"value":462},"incremental materialization",{"type":38,"value":464}," и ",{"type":33,"tag":458,"props":466,"children":467},{},[468],{"type":38,"value":469},"pre-aggregated cohort snapshots",{"type":38,"value":140},{"type":33,"tag":472,"props":473,"children":475},"h3",{"id":474},"incremental-materialization-pipeline-от-событий-к-когортам-через-dbt",[476],{"type":38,"value":477},"Incremental Materialization: pipeline от событий к когортам через dbt",{"type":33,"tag":34,"props":479,"children":480},{},[481,483,489],{"type":38,"value":482},"Вместо расчёта когорт каждый раз, обновляйте накопительную таблицу ежедневными batch'ами. Используя ",{"type":33,"tag":53,"props":484,"children":486},{"className":485},[],[487],{"type":38,"value":488},"incremental",{"type":38,"value":490}," стратегию dbt, вы добавляете события нового дня в существующую таблицу когорт.",{"type":33,"tag":84,"props":492,"children":494},{"className":86,"code":493,"language":88,"meta":16,"style":16},"-- models\u002Fcohort_retention_daily.sql\n{{\n  config(\n    materialized='incremental',\n    partition_by={'field': 'cohort_date', 'data_type': 'date'},\n    cluster_by=['day_n', 'metric_name'],\n    unique_key='cohort_date || day_n || metric_name'\n  )\n}}\n\nWITH new_events AS (\n  SELECT \n    u.user_id,\n    DATE_TRUNC(u.created_at, DAY) AS cohort_date,\n    DATE_DIFF(e.event_date, u.created_at, DAY) AS day_n,\n    e.event_name,\n    e.revenue_usd\n  FROM {{ ref('events') }} e\n  JOIN {{ ref('users') }} u ON e.user_id = u.user_id\n  {% if is_incremental() %}\n  WHERE e.event_date = CURRENT_DATE() - 1  -- только вчерашние данные\n  {% endif %}\n)\nSELECT\n  cohort_date,\n  day_n,\n  'active_users' AS metric_name,\n  COUNT(DISTINCT user_id) AS metric_value\nFROM new_events\nWHERE event_name = 'session_start'\nGROUP BY 1, 2, 3\n\nUNION ALL\n\nSELECT\n  cohort_date,\n  day_n,\n  'revenue_per_cohort' AS metric_name,\n  SUM(revenue_usd) AS metric_value\nFROM new_events\nGROUP BY 1, 2, 3;\n",[495],{"type":33,"tag":53,"props":496,"children":497},{"__ignoreMap":16},[498,506,514,522,545,600,617,634,642,650,659,681,694,715,756,813,834,851,875,930,949,993,1002,1011,1020,1029,1038,1057,1087,1100,1121,1150,1158,1167,1175,1183,1191,1199,1216,1238,1250],{"type":33,"tag":94,"props":499,"children":500},{"class":96,"line":97},[501],{"type":33,"tag":94,"props":502,"children":503},{"style":101},[504],{"type":38,"value":505},"-- models\u002Fcohort_retention_daily.sql\n",{"type":33,"tag":94,"props":507,"children":508},{"class":96,"line":107},[509],{"type":33,"tag":94,"props":510,"children":511},{"style":117},[512],{"type":38,"value":513},"{{\n",{"type":33,"tag":94,"props":515,"children":516},{"class":96,"line":123},[517],{"type":33,"tag":94,"props":518,"children":519},{"style":117},[520],{"type":38,"value":521},"  config(\n",{"type":33,"tag":94,"props":523,"children":524},{"class":96,"line":172},[525,530,535,540],{"type":33,"tag":94,"props":526,"children":527},{"style":117},[528],{"type":38,"value":529},"    materialized",{"type":33,"tag":94,"props":531,"children":532},{"style":111},[533],{"type":38,"value":534},"=",{"type":33,"tag":94,"props":536,"children":537},{"style":368},[538],{"type":38,"value":539},"'incremental'",{"type":33,"tag":94,"props":541,"children":542},{"style":117},[543],{"type":38,"value":544},",\n",{"type":33,"tag":94,"props":546,"children":547},{"class":96,"line":232},[548,553,557,562,567,572,577,581,586,590,595],{"type":33,"tag":94,"props":549,"children":550},{"style":117},[551],{"type":38,"value":552},"    partition_by",{"type":33,"tag":94,"props":554,"children":555},{"style":111},[556],{"type":38,"value":534},{"type":33,"tag":94,"props":558,"children":559},{"style":117},[560],{"type":38,"value":561},"{",{"type":33,"tag":94,"props":563,"children":564},{"style":368},[565],{"type":38,"value":566},"'field'",{"type":33,"tag":94,"props":568,"children":569},{"style":117},[570],{"type":38,"value":571},": ",{"type":33,"tag":94,"props":573,"children":574},{"style":368},[575],{"type":38,"value":576},"'cohort_date'",{"type":33,"tag":94,"props":578,"children":579},{"style":117},[580],{"type":38,"value":60},{"type":33,"tag":94,"props":582,"children":583},{"style":368},[584],{"type":38,"value":585},"'data_type'",{"type":33,"tag":94,"props":587,"children":588},{"style":117},[589],{"type":38,"value":571},{"type":33,"tag":94,"props":591,"children":592},{"style":368},[593],{"type":38,"value":594},"'date'",{"type":33,"tag":94,"props":596,"children":597},{"style":117},[598],{"type":38,"value":599},"},\n",{"type":33,"tag":94,"props":601,"children":602},{"class":96,"line":278},[603,608,612],{"type":33,"tag":94,"props":604,"children":605},{"style":117},[606],{"type":38,"value":607},"    cluster_by",{"type":33,"tag":94,"props":609,"children":610},{"style":111},[611],{"type":38,"value":534},{"type":33,"tag":94,"props":613,"children":614},{"style":117},[615],{"type":38,"value":616},"['day_n', 'metric_name'],\n",{"type":33,"tag":94,"props":618,"children":619},{"class":96,"line":292},[620,625,629],{"type":33,"tag":94,"props":621,"children":622},{"style":117},[623],{"type":38,"value":624},"    unique_key",{"type":33,"tag":94,"props":626,"children":627},{"style":111},[628],{"type":38,"value":534},{"type":33,"tag":94,"props":630,"children":631},{"style":368},[632],{"type":38,"value":633},"'cohort_date || day_n || metric_name'\n",{"type":33,"tag":94,"props":635,"children":636},{"class":96,"line":342},[637],{"type":33,"tag":94,"props":638,"children":639},{"style":117},[640],{"type":38,"value":641},"  )\n",{"type":33,"tag":94,"props":643,"children":644},{"class":96,"line":27},[645],{"type":33,"tag":94,"props":646,"children":647},{"style":117},[648],{"type":38,"value":649},"}}\n",{"type":33,"tag":94,"props":651,"children":652},{"class":96,"line":404},[653],{"type":33,"tag":94,"props":654,"children":656},{"emptyLinePlaceholder":655},true,[657],{"type":38,"value":658},"\n",{"type":33,"tag":94,"props":660,"children":661},{"class":96,"line":427},[662,667,672,676],{"type":33,"tag":94,"props":663,"children":664},{"style":111},[665],{"type":38,"value":666},"WITH",{"type":33,"tag":94,"props":668,"children":669},{"style":117},[670],{"type":38,"value":671}," new_events ",{"type":33,"tag":94,"props":673,"children":674},{"style":111},[675],{"type":38,"value":164},{"type":33,"tag":94,"props":677,"children":678},{"style":117},[679],{"type":38,"value":680}," (\n",{"type":33,"tag":94,"props":682,"children":684},{"class":96,"line":683},12,[685,690],{"type":33,"tag":94,"props":686,"children":687},{"style":111},[688],{"type":38,"value":689},"  SELECT",{"type":33,"tag":94,"props":691,"children":692},{"style":117},[693],{"type":38,"value":120},{"type":33,"tag":94,"props":695,"children":697},{"class":96,"line":696},13,[698,703,707,711],{"type":33,"tag":94,"props":699,"children":700},{"style":132},[701],{"type":38,"value":702},"    u",{"type":33,"tag":94,"props":704,"children":705},{"style":117},[706],{"type":38,"value":140},{"type":33,"tag":94,"props":708,"children":709},{"style":132},[710],{"type":38,"value":262},{"type":33,"tag":94,"props":712,"children":713},{"style":117},[714],{"type":38,"value":544},{"type":33,"tag":94,"props":716,"children":718},{"class":96,"line":717},14,[719,724,728,732,736,740,744,748,752],{"type":33,"tag":94,"props":720,"children":721},{"style":117},[722],{"type":38,"value":723},"    DATE_TRUNC(",{"type":33,"tag":94,"props":725,"children":726},{"style":132},[727],{"type":38,"value":135},{"type":33,"tag":94,"props":729,"children":730},{"style":117},[731],{"type":38,"value":140},{"type":33,"tag":94,"props":733,"children":734},{"style":132},[735],{"type":38,"value":145},{"type":33,"tag":94,"props":737,"children":738},{"style":117},[739],{"type":38,"value":60},{"type":33,"tag":94,"props":741,"children":742},{"style":111},[743],{"type":38,"value":154},{"type":33,"tag":94,"props":745,"children":746},{"style":117},[747],{"type":38,"value":159},{"type":33,"tag":94,"props":749,"children":750},{"style":111},[751],{"type":38,"value":164},{"type":33,"tag":94,"props":753,"children":754},{"style":117},[755],{"type":38,"value":169},{"type":33,"tag":94,"props":757,"children":759},{"class":96,"line":758},15,[760,765,769,773,777,781,785,789,793,797,801,805,809],{"type":33,"tag":94,"props":761,"children":762},{"style":117},[763],{"type":38,"value":764},"    DATE_DIFF(",{"type":33,"tag":94,"props":766,"children":767},{"style":132},[768],{"type":38,"value":183},{"type":33,"tag":94,"props":770,"children":771},{"style":117},[772],{"type":38,"value":140},{"type":33,"tag":94,"props":774,"children":775},{"style":132},[776],{"type":38,"value":192},{"type":33,"tag":94,"props":778,"children":779},{"style":117},[780],{"type":38,"value":60},{"type":33,"tag":94,"props":782,"children":783},{"style":132},[784],{"type":38,"value":135},{"type":33,"tag":94,"props":786,"children":787},{"style":117},[788],{"type":38,"value":140},{"type":33,"tag":94,"props":790,"children":791},{"style":132},[792],{"type":38,"value":145},{"type":33,"tag":94,"props":794,"children":795},{"style":117},[796],{"type":38,"value":60},{"type":33,"tag":94,"props":798,"children":799},{"style":111},[800],{"type":38,"value":154},{"type":33,"tag":94,"props":802,"children":803},{"style":117},[804],{"type":38,"value":159},{"type":33,"tag":94,"props":806,"children":807},{"style":111},[808],{"type":38,"value":164},{"type":33,"tag":94,"props":810,"children":811},{"style":117},[812],{"type":38,"value":229},{"type":33,"tag":94,"props":814,"children":816},{"class":96,"line":815},16,[817,822,826,830],{"type":33,"tag":94,"props":818,"children":819},{"style":132},[820],{"type":38,"value":821},"    e",{"type":33,"tag":94,"props":823,"children":824},{"style":117},[825],{"type":38,"value":140},{"type":33,"tag":94,"props":827,"children":828},{"style":132},[829],{"type":38,"value":392},{"type":33,"tag":94,"props":831,"children":832},{"style":117},[833],{"type":38,"value":544},{"type":33,"tag":94,"props":835,"children":837},{"class":96,"line":836},17,[838,842,846],{"type":33,"tag":94,"props":839,"children":840},{"style":132},[841],{"type":38,"value":821},{"type":33,"tag":94,"props":843,"children":844},{"style":117},[845],{"type":38,"value":140},{"type":33,"tag":94,"props":847,"children":848},{"style":132},[849],{"type":38,"value":850},"revenue_usd\n",{"type":33,"tag":94,"props":852,"children":854},{"class":96,"line":853},18,[855,860,865,870],{"type":33,"tag":94,"props":856,"children":857},{"style":111},[858],{"type":38,"value":859},"  FROM",{"type":33,"tag":94,"props":861,"children":862},{"style":117},[863],{"type":38,"value":864}," {{ ref(",{"type":33,"tag":94,"props":866,"children":867},{"style":368},[868],{"type":38,"value":869},"'events'",{"type":33,"tag":94,"props":871,"children":872},{"style":117},[873],{"type":38,"value":874},") }} e\n",{"type":33,"tag":94,"props":876,"children":878},{"class":96,"line":877},19,[879,884,888,893,898,902,906,910,914,918,922,926],{"type":33,"tag":94,"props":880,"children":881},{"style":111},[882],{"type":38,"value":883},"  JOIN",{"type":33,"tag":94,"props":885,"children":886},{"style":117},[887],{"type":38,"value":864},{"type":33,"tag":94,"props":889,"children":890},{"style":368},[891],{"type":38,"value":892},"'users'",{"type":33,"tag":94,"props":894,"children":895},{"style":117},[896],{"type":38,"value":897},") }} u ",{"type":33,"tag":94,"props":899,"children":900},{"style":111},[901],{"type":38,"value":308},{"type":33,"tag":94,"props":903,"children":904},{"style":132},[905],{"type":38,"value":330},{"type":33,"tag":94,"props":907,"children":908},{"style":117},[909],{"type":38,"value":140},{"type":33,"tag":94,"props":911,"children":912},{"style":132},[913],{"type":38,"value":262},{"type":33,"tag":94,"props":915,"children":916},{"style":111},[917],{"type":38,"value":325},{"type":33,"tag":94,"props":919,"children":920},{"style":132},[921],{"type":38,"value":253},{"type":33,"tag":94,"props":923,"children":924},{"style":117},[925],{"type":38,"value":140},{"type":33,"tag":94,"props":927,"children":928},{"style":132},[929],{"type":38,"value":339},{"type":33,"tag":94,"props":931,"children":933},{"class":96,"line":932},20,[934,939,944],{"type":33,"tag":94,"props":935,"children":936},{"style":117},[937],{"type":38,"value":938},"  {% ",{"type":33,"tag":94,"props":940,"children":941},{"style":111},[942],{"type":38,"value":943},"if",{"type":33,"tag":94,"props":945,"children":946},{"style":117},[947],{"type":38,"value":948}," is_incremental() %}\n",{"type":33,"tag":94,"props":950,"children":952},{"class":96,"line":951},21,[953,958,962,966,970,974,979,984,988],{"type":33,"tag":94,"props":954,"children":955},{"style":111},[956],{"type":38,"value":957},"  WHERE",{"type":33,"tag":94,"props":959,"children":960},{"style":132},[961],{"type":38,"value":330},{"type":33,"tag":94,"props":963,"children":964},{"style":117},[965],{"type":38,"value":140},{"type":33,"tag":94,"props":967,"children":968},{"style":132},[969],{"type":38,"value":192},{"type":33,"tag":94,"props":971,"children":972},{"style":111},[973],{"type":38,"value":325},{"type":33,"tag":94,"props":975,"children":976},{"style":117},[977],{"type":38,"value":978}," CURRENT_DATE() ",{"type":33,"tag":94,"props":980,"children":981},{"style":111},[982],{"type":38,"value":983},"-",{"type":33,"tag":94,"props":985,"children":986},{"style":132},[987],{"type":38,"value":415},{"type":33,"tag":94,"props":989,"children":990},{"style":101},[991],{"type":38,"value":992},"  -- только вчерашние данные\n",{"type":33,"tag":94,"props":994,"children":996},{"class":96,"line":995},22,[997],{"type":33,"tag":94,"props":998,"children":999},{"style":117},[1000],{"type":38,"value":1001},"  {% endif %}\n",{"type":33,"tag":94,"props":1003,"children":1005},{"class":96,"line":1004},23,[1006],{"type":33,"tag":94,"props":1007,"children":1008},{"style":117},[1009],{"type":38,"value":1010},")\n",{"type":33,"tag":94,"props":1012,"children":1014},{"class":96,"line":1013},24,[1015],{"type":33,"tag":94,"props":1016,"children":1017},{"style":111},[1018],{"type":38,"value":1019},"SELECT\n",{"type":33,"tag":94,"props":1021,"children":1023},{"class":96,"line":1022},25,[1024],{"type":33,"tag":94,"props":1025,"children":1026},{"style":117},[1027],{"type":38,"value":1028},"  cohort_date,\n",{"type":33,"tag":94,"props":1030,"children":1032},{"class":96,"line":1031},26,[1033],{"type":33,"tag":94,"props":1034,"children":1035},{"style":117},[1036],{"type":38,"value":1037},"  day_n,\n",{"type":33,"tag":94,"props":1039,"children":1041},{"class":96,"line":1040},27,[1042,1047,1052],{"type":33,"tag":94,"props":1043,"children":1044},{"style":368},[1045],{"type":38,"value":1046},"  'active_users'",{"type":33,"tag":94,"props":1048,"children":1049},{"style":111},[1050],{"type":38,"value":1051}," AS",{"type":33,"tag":94,"props":1053,"children":1054},{"style":117},[1055],{"type":38,"value":1056}," metric_name,\n",{"type":33,"tag":94,"props":1058,"children":1060},{"class":96,"line":1059},28,[1061,1065,1069,1073,1078,1082],{"type":33,"tag":94,"props":1062,"children":1063},{"style":132},[1064],{"type":38,"value":238},{"type":33,"tag":94,"props":1066,"children":1067},{"style":117},[1068],{"type":38,"value":243},{"type":33,"tag":94,"props":1070,"children":1071},{"style":111},[1072],{"type":38,"value":248},{"type":33,"tag":94,"props":1074,"children":1075},{"style":117},[1076],{"type":38,"value":1077}," user_id) ",{"type":33,"tag":94,"props":1079,"children":1080},{"style":111},[1081],{"type":38,"value":164},{"type":33,"tag":94,"props":1083,"children":1084},{"style":117},[1085],{"type":38,"value":1086}," metric_value\n",{"type":33,"tag":94,"props":1088,"children":1090},{"class":96,"line":1089},29,[1091,1095],{"type":33,"tag":94,"props":1092,"children":1093},{"style":111},[1094],{"type":38,"value":284},{"type":33,"tag":94,"props":1096,"children":1097},{"style":117},[1098],{"type":38,"value":1099}," new_events\n",{"type":33,"tag":94,"props":1101,"children":1103},{"class":96,"line":1102},30,[1104,1108,1113,1117],{"type":33,"tag":94,"props":1105,"children":1106},{"style":111},[1107],{"type":38,"value":348},{"type":33,"tag":94,"props":1109,"children":1110},{"style":117},[1111],{"type":38,"value":1112}," event_name ",{"type":33,"tag":94,"props":1114,"children":1115},{"style":111},[1116],{"type":38,"value":534},{"type":33,"tag":94,"props":1118,"children":1119},{"style":368},[1120],{"type":38,"value":401},{"type":33,"tag":94,"props":1122,"children":1124},{"class":96,"line":1123},31,[1125,1129,1133,1137,1141,1145],{"type":33,"tag":94,"props":1126,"children":1127},{"style":111},[1128],{"type":38,"value":410},{"type":33,"tag":94,"props":1130,"children":1131},{"style":132},[1132],{"type":38,"value":415},{"type":33,"tag":94,"props":1134,"children":1135},{"style":117},[1136],{"type":38,"value":60},{"type":33,"tag":94,"props":1138,"children":1139},{"style":132},[1140],{"type":38,"value":446},{"type":33,"tag":94,"props":1142,"children":1143},{"style":117},[1144],{"type":38,"value":60},{"type":33,"tag":94,"props":1146,"children":1147},{"style":132},[1148],{"type":38,"value":1149},"3\n",{"type":33,"tag":94,"props":1151,"children":1153},{"class":96,"line":1152},32,[1154],{"type":33,"tag":94,"props":1155,"children":1156},{"emptyLinePlaceholder":655},[1157],{"type":38,"value":658},{"type":33,"tag":94,"props":1159,"children":1161},{"class":96,"line":1160},33,[1162],{"type":33,"tag":94,"props":1163,"children":1164},{"style":111},[1165],{"type":38,"value":1166},"UNION ALL\n",{"type":33,"tag":94,"props":1168,"children":1170},{"class":96,"line":1169},34,[1171],{"type":33,"tag":94,"props":1172,"children":1173},{"emptyLinePlaceholder":655},[1174],{"type":38,"value":658},{"type":33,"tag":94,"props":1176,"children":1178},{"class":96,"line":1177},35,[1179],{"type":33,"tag":94,"props":1180,"children":1181},{"style":111},[1182],{"type":38,"value":1019},{"type":33,"tag":94,"props":1184,"children":1186},{"class":96,"line":1185},36,[1187],{"type":33,"tag":94,"props":1188,"children":1189},{"style":117},[1190],{"type":38,"value":1028},{"type":33,"tag":94,"props":1192,"children":1194},{"class":96,"line":1193},37,[1195],{"type":33,"tag":94,"props":1196,"children":1197},{"style":117},[1198],{"type":38,"value":1037},{"type":33,"tag":94,"props":1200,"children":1202},{"class":96,"line":1201},38,[1203,1208,1212],{"type":33,"tag":94,"props":1204,"children":1205},{"style":368},[1206],{"type":38,"value":1207},"  'revenue_per_cohort'",{"type":33,"tag":94,"props":1209,"children":1210},{"style":111},[1211],{"type":38,"value":1051},{"type":33,"tag":94,"props":1213,"children":1214},{"style":117},[1215],{"type":38,"value":1056},{"type":33,"tag":94,"props":1217,"children":1219},{"class":96,"line":1218},39,[1220,1225,1230,1234],{"type":33,"tag":94,"props":1221,"children":1222},{"style":132},[1223],{"type":38,"value":1224},"  SUM",{"type":33,"tag":94,"props":1226,"children":1227},{"style":117},[1228],{"type":38,"value":1229},"(revenue_usd) ",{"type":33,"tag":94,"props":1231,"children":1232},{"style":111},[1233],{"type":38,"value":164},{"type":33,"tag":94,"props":1235,"children":1236},{"style":117},[1237],{"type":38,"value":1086},{"type":33,"tag":94,"props":1239,"children":1241},{"class":96,"line":1240},40,[1242,1246],{"type":33,"tag":94,"props":1243,"children":1244},{"style":111},[1245],{"type":38,"value":284},{"type":33,"tag":94,"props":1247,"children":1248},{"style":117},[1249],{"type":38,"value":1099},{"type":33,"tag":94,"props":1251,"children":1253},{"class":96,"line":1252},41,[1254,1258,1262,1266,1270,1274,1279],{"type":33,"tag":94,"props":1255,"children":1256},{"style":111},[1257],{"type":38,"value":410},{"type":33,"tag":94,"props":1259,"children":1260},{"style":132},[1261],{"type":38,"value":415},{"type":33,"tag":94,"props":1263,"children":1264},{"style":117},[1265],{"type":38,"value":60},{"type":33,"tag":94,"props":1267,"children":1268},{"style":132},[1269],{"type":38,"value":446},{"type":33,"tag":94,"props":1271,"children":1272},{"style":117},[1273],{"type":38,"value":60},{"type":33,"tag":94,"props":1275,"children":1276},{"style":132},[1277],{"type":38,"value":1278},"3",{"type":33,"tag":94,"props":1280,"children":1281},{"style":117},[1282],{"type":38,"value":451},{"type":33,"tag":34,"props":1284,"children":1285},{},[1286],{"type":38,"value":1287},"Первый запуск (full refresh) обрабатывает все исторические данные. Каждый следующий день добавляются только новые события за 1 день. Один день из 100M событий сканирует 3,2GB данных (благодаря partitioning и clustering), запрос работает 4 секунды, стоит 0,016 доллара. Итоговая ежемесячная стоимость incremental: 0,48 доллара — в 300.000 раз дешевле, чем наивный подход.",{"type":33,"tag":41,"props":1289,"children":1291},{"id":1290},"materialized-views-автоматический-слой-кэширования-bigquery",[1292],{"type":38,"value":1293},"Materialized Views: автоматический слой кэширования BigQuery",{"type":33,"tag":34,"props":1295,"children":1296},{},[1297,1299,1304],{"type":38,"value":1298},"Incremental модель обновляется batch'ами (один раз в день). Если для real-time dashboard нужно добавить данные за последний час, в дело вступает ",{"type":33,"tag":458,"props":1300,"children":1301},{},[1302],{"type":38,"value":1303},"materialized view",{"type":38,"value":1305}," BigQuery. Materialized view физически сохраняет результат базового запроса и автоматически обновляется при изменении исходной таблицы.",{"type":33,"tag":84,"props":1307,"children":1309},{"className":86,"code":1308,"language":88,"meta":16,"style":16},"CREATE MATERIALIZED VIEW `project.dataset.cohort_retention_mv`\nPARTITION BY cohort_date\nCLUSTER BY day_n, metric_name\nAS\nSELECT\n  DATE_TRUNC(u.created_at, DAY) AS cohort_date,\n  DATE_DIFF(e.event_date, u.created_at, DAY) AS day_n,\n  'active_users' AS metric_name,\n  COUNT(DISTINCT u.user_id) AS metric_value\nFROM `project.dataset.events` e\nJOIN `project.dataset.users` u ON e.user_id = u.user_id\nWHERE e.event_date >= CURRENT_DATE() - 90  -- только 90-дневное окно\n  AND e.event_name = 'session_start'\nGROUP BY 1, 2, 3;\n",[1310],{"type":33,"tag":53,"props":1311,"children":1312},{"__ignoreMap":16},[1313,1331,1349,1367,1375,1382,1421,1476,1491,1530,1547,1596,1637,1664],{"type":33,"tag":94,"props":1314,"children":1315},{"class":96,"line":97},[1316,1321,1326],{"type":33,"tag":94,"props":1317,"children":1318},{"style":111},[1319],{"type":38,"value":1320},"CREATE",{"type":33,"tag":94,"props":1322,"children":1323},{"style":117},[1324],{"type":38,"value":1325}," MATERIALIZED VIEW ",{"type":33,"tag":94,"props":1327,"children":1328},{"style":368},[1329],{"type":38,"value":1330},"`project.dataset.cohort_retention_mv`\n",{"type":33,"tag":94,"props":1332,"children":1333},{"class":96,"line":107},[1334,1339,1344],{"type":33,"tag":94,"props":1335,"children":1336},{"style":111},[1337],{"type":38,"value":1338},"PARTITION",{"type":33,"tag":94,"props":1340,"children":1341},{"style":111},[1342],{"type":38,"value":1343}," BY",{"type":33,"tag":94,"props":1345,"children":1346},{"style":117},[1347],{"type":38,"value":1348}," cohort_date\n",{"type":33,"tag":94,"props":1350,"children":1351},{"class":96,"line":123},[1352,1357,1362],{"type":33,"tag":94,"props":1353,"children":1354},{"style":117},[1355],{"type":38,"value":1356},"CLUSTER ",{"type":33,"tag":94,"props":1358,"children":1359},{"style":111},[1360],{"type":38,"value":1361},"BY",{"type":33,"tag":94,"props":1363,"children":1364},{"style":117},[1365],{"type":38,"value":1366}," day_n, metric_name\n",{"type":33,"tag":94,"props":1368,"children":1369},{"class":96,"line":172},[1370],{"type":33,"tag":94,"props":1371,"children":1372},{"style":111},[1373],{"type":38,"value":1374},"AS\n",{"type":33,"tag":94,"props":1376,"children":1377},{"class":96,"line":232},[1378],{"type":33,"tag":94,"props":1379,"children":1380},{"style":111},[1381],{"type":38,"value":1019},{"type":33,"tag":94,"props":1383,"children":1384},{"class":96,"line":278},[1385,1389,1393,1397,1401,1405,1409,1413,1417],{"type":33,"tag":94,"props":1386,"children":1387},{"style":117},[1388],{"type":38,"value":129},{"type":33,"tag":94,"props":1390,"children":1391},{"style":132},[1392],{"type":38,"value":135},{"type":33,"tag":94,"props":1394,"children":1395},{"style":117},[1396],{"type":38,"value":140},{"type":33,"tag":94,"props":1398,"children":1399},{"style":132},[1400],{"type":38,"value":145},{"type":33,"tag":94,"props":1402,"children":1403},{"style":117},[1404],{"type":38,"value":60},{"type":33,"tag":94,"props":1406,"children":1407},{"style":111},[1408],{"type":38,"value":154},{"type":33,"tag":94,"props":1410,"children":1411},{"style":117},[1412],{"type":38,"value":159},{"type":33,"tag":94,"props":1414,"children":1415},{"style":111},[1416],{"type":38,"value":164},{"type":33,"tag":94,"props":1418,"children":1419},{"style":117},[1420],{"type":38,"value":169},{"type":33,"tag":94,"props":1422,"children":1423},{"class":96,"line":292},[1424,1428,1432,1436,1440,1444,1448,1452,1456,1460,1464,1468,1472],{"type":33,"tag":94,"props":1425,"children":1426},{"style":117},[1427],{"type":38,"value":178},{"type":33,"tag":94,"props":1429,"children":1430},{"style":132},[1431],{"type":38,"value":183},{"type":33,"tag":94,"props":1433,"children":1434},{"style":117},[1435],{"type":38,"value":140},{"type":33,"tag":94,"props":1437,"children":1438},{"style":132},[1439],{"type":38,"value":192},{"type":33,"tag":94,"props":1441,"children":1442},{"style":117},[1443],{"type":38,"value":60},{"type":33,"tag":94,"props":1445,"children":1446},{"style":132},[1447],{"type":38,"value":135},{"type":33,"tag":94,"props":1449,"children":1450},{"style":117},[1451],{"type":38,"value":140},{"type":33,"tag":94,"props":1453,"children":1454},{"style":132},[1455],{"type":38,"value":145},{"type":33,"tag":94,"props":1457,"children":1458},{"style":117},[1459],{"type":38,"value":60},{"type":33,"tag":94,"props":1461,"children":1462},{"style":111},[1463],{"type":38,"value":154},{"type":33,"tag":94,"props":1465,"children":1466},{"style":117},[1467],{"type":38,"value":159},{"type":33,"tag":94,"props":1469,"children":1470},{"style":111},[1471],{"type":38,"value":164},{"type":33,"tag":94,"props":1473,"children":1474},{"style":117},[1475],{"type":38,"value":229},{"type":33,"tag":94,"props":1477,"children":1478},{"class":96,"line":342},[1479,1483,1487],{"type":33,"tag":94,"props":1480,"children":1481},{"style":368},[1482],{"type":38,"value":1046},{"type":33,"tag":94,"props":1484,"children":1485},{"style":111},[1486],{"type":38,"value":1051},{"type":33,"tag":94,"props":1488,"children":1489},{"style":117},[1490],{"type":38,"value":1056},{"type":33,"tag":94,"props":1492,"children":1493},{"class":96,"line":27},[1494,1498,1502,1506,1510,1514,1518,1522,1526],{"type":33,"tag":94,"props":1495,"children":1496},{"style":132},[1497],{"type":38,"value":238},{"type":33,"tag":94,"props":1499,"children":1500},{"style":117},[1501],{"type":38,"value":243},{"type":33,"tag":94,"props":1503,"children":1504},{"style":111},[1505],{"type":38,"value":248},{"type":33,"tag":94,"props":1507,"children":1508},{"style":132},[1509],{"type":38,"value":253},{"type":33,"tag":94,"props":1511,"children":1512},{"style":117},[1513],{"type":38,"value":140},{"type":33,"tag":94,"props":1515,"children":1516},{"style":132},[1517],{"type":38,"value":262},{"type":33,"tag":94,"props":1519,"children":1520},{"style":117},[1521],{"type":38,"value":159},{"type":33,"tag":94,"props":1523,"children":1524},{"style":111},[1525],{"type":38,"value":164},{"type":33,"tag":94,"props":1527,"children":1528},{"style":117},[1529],{"type":38,"value":1086},{"type":33,"tag":94,"props":1531,"children":1532},{"class":96,"line":404},[1533,1537,1542],{"type":33,"tag":94,"props":1534,"children":1535},{"style":111},[1536],{"type":38,"value":284},{"type":33,"tag":94,"props":1538,"children":1539},{"style":368},[1540],{"type":38,"value":1541}," `project.dataset.events`",{"type":33,"tag":94,"props":1543,"children":1544},{"style":117},[1545],{"type":38,"value":1546}," e\n",{"type":33,"tag":94,"props":1548,"children":1549},{"class":96,"line":427},[1550,1554,1559,1564,1568,1572,1576,1580,1584,1588,1592],{"type":33,"tag":94,"props":1551,"children":1552},{"style":111},[1553],{"type":38,"value":298},{"type":33,"tag":94,"props":1555,"children":1556},{"style":368},[1557],{"type":38,"value":1558}," `project.dataset.users`",{"type":33,"tag":94,"props":1560,"children":1561},{"style":117},[1562],{"type":38,"value":1563}," u ",{"type":33,"tag":94,"props":1565,"children":1566},{"style":111},[1567],{"type":38,"value":308},{"type":33,"tag":94,"props":1569,"children":1570},{"style":132},[1571],{"type":38,"value":330},{"type":33,"tag":94,"props":1573,"children":1574},{"style":117},[1575],{"type":38,"value":140},{"type":33,"tag":94,"props":1577,"children":1578},{"style":132},[1579],{"type":38,"value":262},{"type":33,"tag":94,"props":1581,"children":1582},{"style":111},[1583],{"type":38,"value":325},{"type":33,"tag":94,"props":1585,"children":1586},{"style":132},[1587],{"type":38,"value":253},{"type":33,"tag":94,"props":1589,"children":1590},{"style":117},[1591],{"type":38,"value":140},{"type":33,"tag":94,"props":1593,"children":1594},{"style":132},[1595],{"type":38,"value":339},{"type":33,"tag":94,"props":1597,"children":1598},{"class":96,"line":683},[1599,1603,1607,1611,1615,1619,1623,1627,1632],{"type":33,"tag":94,"props":1600,"children":1601},{"style":111},[1602],{"type":38,"value":348},{"type":33,"tag":94,"props":1604,"children":1605},{"style":132},[1606],{"type":38,"value":330},{"type":33,"tag":94,"props":1608,"children":1609},{"style":117},[1610],{"type":38,"value":140},{"type":33,"tag":94,"props":1612,"children":1613},{"style":132},[1614],{"type":38,"value":192},{"type":33,"tag":94,"props":1616,"children":1617},{"style":111},[1618],{"type":38,"value":365},{"type":33,"tag":94,"props":1620,"children":1621},{"style":117},[1622],{"type":38,"value":978},{"type":33,"tag":94,"props":1624,"children":1625},{"style":111},[1626],{"type":38,"value":983},{"type":33,"tag":94,"props":1628,"children":1629},{"style":132},[1630],{"type":38,"value":1631}," 90",{"type":33,"tag":94,"props":1633,"children":1634},{"style":101},[1635],{"type":38,"value":1636},"  -- только 90-дневное окно\n",{"type":33,"tag":94,"props":1638,"children":1639},{"class":96,"line":696},[1640,1644,1648,1652,1656,1660],{"type":33,"tag":94,"props":1641,"children":1642},{"style":111},[1643],{"type":38,"value":379},{"type":33,"tag":94,"props":1645,"children":1646},{"style":132},[1647],{"type":38,"value":330},{"type":33,"tag":94,"props":1649,"children":1650},{"style":117},[1651],{"type":38,"value":140},{"type":33,"tag":94,"props":1653,"children":1654},{"style":132},[1655],{"type":38,"value":392},{"type":33,"tag":94,"props":1657,"children":1658},{"style":111},[1659],{"type":38,"value":325},{"type":33,"tag":94,"props":1661,"children":1662},{"style":368},[1663],{"type":38,"value":401},{"type":33,"tag":94,"props":1665,"children":1666},{"class":96,"line":717},[1667,1671,1675,1679,1683,1687,1691],{"type":33,"tag":94,"props":1668,"children":1669},{"style":111},[1670],{"type":38,"value":410},{"type":33,"tag":94,"props":1672,"children":1673},{"style":132},[1674],{"type":38,"value":415},{"type":33,"tag":94,"props":1676,"children":1677},{"style":117},[1678],{"type":38,"value":60},{"type":33,"tag":94,"props":1680,"children":1681},{"style":132},[1682],{"type":38,"value":446},{"type":33,"tag":94,"props":1684,"children":1685},{"style":117},[1686],{"type":38,"value":60},{"type":33,"tag":94,"props":1688,"children":1689},{"style":132},[1690],{"type":38,"value":1278},{"type":33,"tag":94,"props":1692,"children":1693},{"style":117},[1694],{"type":38,"value":451},{"type":33,"tag":34,"props":1696,"children":1697},{},[1698],{"type":38,"value":1699},"При запросе к materialized view BigQuery сначала возвращает кэшированный результат. Если исходная таблица изменяется (добавляются новые события), в фоне вычисляется дельта. Запрос dashboard'а теперь работает за 0,2 секунды, стоит 0 долларов (cache hit). Но учтите: сама materialized view создаёт расходы на хранилище (BigQuery storage: 0,02$\u002FGB\u002Fмесяц), и если 90-дневная таблица когорт занимает 12GB, это добавляет 0,24 доллара ежемесячных расходов.",{"type":33,"tag":34,"props":1701,"children":1702},{},[1703],{"type":33,"tag":458,"props":1704,"children":1705},{},[1706],{"type":38,"value":1707},"Таблица компромиссов:",{"type":33,"tag":1709,"props":1710,"children":1711},"table",{},[1712,1746],{"type":33,"tag":1713,"props":1714,"children":1715},"thead",{},[1716],{"type":33,"tag":1717,"props":1718,"children":1719},"tr",{},[1720,1726,1731,1736,1741],{"type":33,"tag":1721,"props":1722,"children":1723},"th",{},[1724],{"type":38,"value":1725},"Метод",{"type":33,"tag":1721,"props":1727,"children":1728},{},[1729],{"type":38,"value":1730},"Время первого запроса",{"type":33,"tag":1721,"props":1732,"children":1733},{},[1734],{"type":38,"value":1735},"Время запроса dashboard",{"type":33,"tag":1721,"props":1737,"children":1738},{},[1739],{"type":38,"value":1740},"Ежемесячные расходы вычислений",{"type":33,"tag":1721,"props":1742,"children":1743},{},[1744],{"type":38,"value":1745},"Ежемесячные расходы хранилища",{"type":33,"tag":1747,"props":1748,"children":1749},"tbody",{},[1750,1778,1806],{"type":33,"tag":1717,"props":1751,"children":1752},{},[1753,1759,1764,1768,1773],{"type":33,"tag":1754,"props":1755,"children":1756},"td",{},[1757],{"type":38,"value":1758},"Naive JOIN",{"type":33,"tag":1754,"props":1760,"children":1761},{},[1762],{"type":38,"value":1763},"12s",{"type":33,"tag":1754,"props":1765,"children":1766},{},[1767],{"type":38,"value":1763},{"type":33,"tag":1754,"props":1769,"children":1770},{},[1771],{"type":38,"value":1772},"144.000$",{"type":33,"tag":1754,"props":1774,"children":1775},{},[1776],{"type":38,"value":1777},"0$",{"type":33,"tag":1717,"props":1779,"children":1780},{},[1781,1786,1791,1796,1801],{"type":33,"tag":1754,"props":1782,"children":1783},{},[1784],{"type":38,"value":1785},"dbt Incremental",{"type":33,"tag":1754,"props":1787,"children":1788},{},[1789],{"type":38,"value":1790},"4s (первый batch)",{"type":33,"tag":1754,"props":1792,"children":1793},{},[1794],{"type":38,"value":1795},"2s (чтение снимка)",{"type":33,"tag":1754,"props":1797,"children":1798},{},[1799],{"type":38,"value":1800},"0,48$",{"type":33,"tag":1754,"props":1802,"children":1803},{},[1804],{"type":38,"value":1805},"0,18$ (таблица снимков)",{"type":33,"tag":1717,"props":1807,"children":1808},{},[1809,1814,1819,1824,1829],{"type":33,"tag":1754,"props":1810,"children":1811},{},[1812],{"type":38,"value":1813},"Materialized View",{"type":33,"tag":1754,"props":1815,"children":1816},{},[1817],{"type":38,"value":1818},"8s (первая сборка)",{"type":33,"tag":1754,"props":1820,"children":1821},{},[1822],{"type":38,"value":1823},"0,2s (cache hit)",{"type":33,"tag":1754,"props":1825,"children":1826},{},[1827],{"type":38,"value":1828},"0$ (автоматическое обновление)",{"type":33,"tag":1754,"props":1830,"children":1831},{},[1832],{"type":38,"value":1833},"0,24$",{"type":33,"tag":34,"props":1835,"children":1836},{},[1837,1839,1844,1846,1850],{"type":38,"value":1838},"В production идеально сочетание обоих подходов: ",{"type":33,"tag":458,"props":1840,"children":1841},{},[1842],{"type":38,"value":1843},"dbt incremental модель",{"type":38,"value":1845}," обновляет исторические когорты ежедневным batch'ем, а ",{"type":33,"tag":458,"props":1847,"children":1848},{},[1849],{"type":38,"value":1303},{"type":38,"value":1851}," поддерживает последние 7 дней в real-time.",{"type":33,"tag":41,"props":1853,"children":1855},{"id":1854},"partitioning-и-clustering-снижение-стоимости-запросов-на-97",[1856],{"type":38,"value":1857},"Partitioning и Clustering: снижение стоимости запросов на 97%",{"type":33,"tag":34,"props":1859,"children":1860},{},[1861],{"type":38,"value":1862},"Если ваши таблицы когорт не разбиты на партиции и не имеют кластеризации, BigQuery сканирует всю таблицу для каждого запроса. На таблице когорт из 1TB (2 года данных) один запрос типа «показать когорту января 2026» сканирует 1TB, стоит 5 долларов. С partitioning + clustering тот же запрос сканирует 8GB, стоит 0,04 доллара.",{"type":33,"tag":34,"props":1864,"children":1865},{},[1866,1871,1873,1879],{"type":33,"tag":458,"props":1867,"children":1868},{},[1869],{"type":38,"value":1870},"Стратегия partitioning:",{"type":38,"value":1872}," разбить по полю ",{"type":33,"tag":53,"props":1874,"children":1876},{"className":1875},[],[1877],{"type":38,"value":1878},"cohort_date",{"type":38,"value":1880}," с дневной детализацией. Когда BigQuery видит фильтр по partition в запросе, она сканирует только релевантные партиции.",{"type":33,"tag":84,"props":1882,"children":1884},{"className":86,"code":1883,"language":88,"meta":16,"style":16},"CREATE OR REPLACE TABLE `project.dataset.cohort_retention`\nPARTITION BY cohort_date\nCLUSTER BY day_n, metric_name\nAS\nSELECT * FROM `project.dataset.cohort_retention_temp`;\n",[1885],{"type":33,"tag":53,"props":1886,"children":1887},{"__ignoreMap":16},[1888,1915,1930,1945,1952],{"type":33,"tag":94,"props":1889,"children":1890},{"class":96,"line":97},[1891,1895,1900,1905,1910],{"type":33,"tag":94,"props":1892,"children":1893},{"style":111},[1894],{"type":38,"value":1320},{"type":33,"tag":94,"props":1896,"children":1897},{"style":111},[1898],{"type":38,"value":1899}," OR",{"type":33,"tag":94,"props":1901,"children":1902},{"style":111},[1903],{"type":38,"value":1904}," REPLACE",{"type":33,"tag":94,"props":1906,"children":1907},{"style":111},[1908],{"type":38,"value":1909}," TABLE",{"type":33,"tag":94,"props":1911,"children":1912},{"style":368},[1913],{"type":38,"value":1914}," `project.dataset.cohort_retention`\n",{"type":33,"tag":94,"props":1916,"children":1917},{"class":96,"line":107},[1918,1922,1926],{"type":33,"tag":94,"props":1919,"children":1920},{"style":111},[1921],{"type":38,"value":1338},{"type":33,"tag":94,"props":1923,"children":1924},{"style":111},[1925],{"type":38,"value":1343},{"type":33,"tag":94,"props":1927,"children":1928},{"style":117},[1929],{"type":38,"value":1348},{"type":33,"tag":94,"props":1931,"children":1932},{"class":96,"line":123},[1933,1937,1941],{"type":33,"tag":94,"props":1934,"children":1935},{"style":117},[1936],{"type":38,"value":1356},{"type":33,"tag":94,"props":1938,"children":1939},{"style":111},[1940],{"type":38,"value":1361},{"type":33,"tag":94,"props":1942,"children":1943},{"style":117},[1944],{"type":38,"value":1366},{"type":33,"tag":94,"props":1946,"children":1947},{"class":96,"line":172},[1948],{"type":33,"tag":94,"props":1949,"children":1950},{"style":111},[1951],{"type":38,"value":1374},{"type":33,"tag":94,"props":1953,"children":1954},{"class":96,"line":232},[1955,1959,1964,1969,1974],{"type":33,"tag":94,"props":1956,"children":1957},{"style":111},[1958],{"type":38,"value":114},{"type":33,"tag":94,"props":1960,"children":1961},{"style":111},[1962],{"type":38,"value":1963}," *",{"type":33,"tag":94,"props":1965,"children":1966},{"style":111},[1967],{"type":38,"value":1968}," FROM",{"type":33,"tag":94,"props":1970,"children":1971},{"style":368},[1972],{"type":38,"value":1973}," `project.dataset.cohort_retention_temp`",{"type":33,"tag":94,"props":1975,"children":1976},{"style":117},[1977],{"type":38,"value":451},{"type":33,"tag":34,"props":1979,"children":1980},{},[1981,1986,1988,1994,1995,2001],{"type":33,"tag":458,"props":1982,"children":1983},{},[1984],{"type":38,"value":1985},"Clustering:",{"type":38,"value":1987}," если внутри partition часто фильтруют определённые поля (например ",{"type":33,"tag":53,"props":1989,"children":1991},{"className":1990},[],[1992],{"type":38,"value":1993},"day_n",{"type":38,"value":60},{"type":33,"tag":53,"props":1996,"children":1998},{"className":1997},[],[1999],{"type":38,"value":2000},"metric_name",{"type":38,"value":2002},"), задайте их как кластеры. BigQuery будет выполнять block-level pruning. Запрос «покажи retention на day_7 + метрику active_users» сканирует только релевантные блоки.",{"type":33,"tag":34,"props":2004,"children":2005},{},[2006,2008,2014,2016,2021],{"type":38,"value":2007},"Конкретный пример: 365 партиций (по дням), каждая 3GB, без clustering запрос ",{"type":33,"tag":53,"props":2009,"children":2011},{"className":2010},[],[2012],{"type":38,"value":2013},"day_n=7",{"type":38,"value":2015}," сканирует 365 партиций × 3GB = 1TB. С clustering сканируются только блоки ",{"type":33,"tag":53,"props":2017,"children":2019},{"className":2018},[],[2020],{"type":38,"value":2013},{"type":38,"value":2022},", всего 12GB. Разница в стоимости: 5$ → 0,06$.",{"type":33,"tag":34,"props":2024,"children":2025},{},[2026,2031,2033,2038,2040,2045],{"type":33,"tag":458,"props":2027,"children":2028},{},[2029],{"type":38,"value":2030},"Anti-pattern:",{"type":38,"value":2032}," не кластеризуйте по ",{"type":33,"tag":53,"props":2034,"children":2036},{"className":2035},[],[2037],{"type":38,"value":262},{"type":38,"value":2039},". Анализ когорт — это не user-level, а cohort-level агрегация. Кластеризация по ",{"type":33,"tag":53,"props":2041,"children":2043},{"className":2042},[],[2044],{"type":38,"value":262},{"type":38,"value":2046}," не помогает query planner'у и снижает эффективность кэша.",{"type":33,"tag":41,"props":2048,"children":2050},{"id":2049},"identity-resolution-для-точности-когорт",[2051],{"type":38,"value":2052},"Identity Resolution для точности когорт",{"type":33,"tag":34,"props":2054,"children":2055},{},[2056,2058,2063,2065,2074,2076,2082,2084,2089],{"type":38,"value":2057},"Точность анализа когорт зависит от точности ",{"type":33,"tag":53,"props":2059,"children":2061},{"className":2060},[],[2062],{"type":38,"value":262},{"type":38,"value":2064},". Когда сессия с cookie и сессия после логина относятся к одному пользователю, но наивный JOIN создаёт два отдельных записи когорт, возникает ошибка. Эту проблему решает подход из ",{"type":33,"tag":2066,"props":2067,"children":2071},"a",{"href":2068,"rel":2069},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Ffirstparty",[2070],"nofollow",[2072],{"type":38,"value":2073},"First-Party Data & Measurement Architecture",{"type":38,"value":2075},": строится identity graph между анонимным ",{"type":33,"tag":53,"props":2077,"children":2079},{"className":2078},[],[2080],{"type":38,"value":2081},"client_id",{"type":38,"value":2083}," и аутентифицированным ",{"type":33,"tag":53,"props":2085,"children":2087},{"className":2086},[],[2088],{"type":38,"value":262},{"type":38,"value":140},{"type":33,"tag":84,"props":2091,"children":2093},{"className":86,"code":2092,"language":88,"meta":16,"style":16},"-- Таблица разрешения идентичности\nCREATE TABLE `project.dataset.identity_graph` (\n  canonical_user_id STRING,\n  client_id STRING,\n  user_id STRING,\n  merged_at TIMESTAMP\n)\nPARTITION BY DATE(merged_at)\nCLUSTER BY canonical_user_id;\n\n-- Объединение с запросом когорты\nWITH resolved_users AS (\n  SELECT \n    COALESCE(ig.canonical_user_id, e.user_id) AS user_id,\n    e.event_date,\n    e.event_name\n  FROM events e\n  LEFT JOIN identity_graph ig \n    ON e.client_id = ig.client_id OR e.user_id = ig.user_id\n)\nSELECT \n  DATE_TRUNC(u.created_at, DAY) AS cohort_date,\n  DATE_DIFF(r.event_date, u.created_at, DAY) AS day_n,\n  COUNT(DISTINCT r.user_id) AS retained_users\nFROM resolved_users r\nJOIN users u ON r.user_id = u.user_id\nGROUP BY 1, 2;\n",[2094],{"type":33,"tag":53,"props":2095,"children":2096},{"__ignoreMap":16},[2097,2105,2125,2133,2141,2149,2162,2169,2190,2206,2213,2221,2241,2252,2307,2326,2342,2354,2367,2436,2443,2454,2493,2549,2589,2601,2645],{"type":33,"tag":94,"props":2098,"children":2099},{"class":96,"line":97},[2100],{"type":33,"tag":94,"props":2101,"children":2102},{"style":101},[2103],{"type":38,"value":2104},"-- Таблица разрешения идентичности\n",{"type":33,"tag":94,"props":2106,"children":2107},{"class":96,"line":107},[2108,2112,2116,2121],{"type":33,"tag":94,"props":2109,"children":2110},{"style":111},[2111],{"type":38,"value":1320},{"type":33,"tag":94,"props":2113,"children":2114},{"style":111},[2115],{"type":38,"value":1909},{"type":33,"tag":94,"props":2117,"children":2118},{"style":368},[2119],{"type":38,"value":2120}," `project.dataset.identity_graph`",{"type":33,"tag":94,"props":2122,"children":2123},{"style":117},[2124],{"type":38,"value":680},{"type":33,"tag":94,"props":2126,"children":2127},{"class":96,"line":123},[2128],{"type":33,"tag":94,"props":2129,"children":2130},{"style":117},[2131],{"type":38,"value":2132},"  canonical_user_id STRING,\n",{"type":33,"tag":94,"props":2134,"children":2135},{"class":96,"line":172},[2136],{"type":33,"tag":94,"props":2137,"children":2138},{"style":117},[2139],{"type":38,"value":2140},"  client_id STRING,\n",{"type":33,"tag":94,"props":2142,"children":2143},{"class":96,"line":232},[2144],{"type":33,"tag":94,"props":2145,"children":2146},{"style":117},[2147],{"type":38,"value":2148},"  user_id STRING,\n",{"type":33,"tag":94,"props":2150,"children":2151},{"class":96,"line":278},[2152,2157],{"type":33,"tag":94,"props":2153,"children":2154},{"style":117},[2155],{"type":38,"value":2156},"  merged_at ",{"type":33,"tag":94,"props":2158,"children":2159},{"style":111},[2160],{"type":38,"value":2161},"TIMESTAMP\n",{"type":33,"tag":94,"props":2163,"children":2164},{"class":96,"line":292},[2165],{"type":33,"tag":94,"props":2166,"children":2167},{"style":117},[2168],{"type":38,"value":1010},{"type":33,"tag":94,"props":2170,"children":2171},{"class":96,"line":342},[2172,2176,2180,2185],{"type":33,"tag":94,"props":2173,"children":2174},{"style":111},[2175],{"type":38,"value":1338},{"type":33,"tag":94,"props":2177,"children":2178},{"style":111},[2179],{"type":38,"value":1343},{"type":33,"tag":94,"props":2181,"children":2182},{"style":111},[2183],{"type":38,"value":2184}," DATE",{"type":33,"tag":94,"props":2186,"children":2187},{"style":117},[2188],{"type":38,"value":2189},"(merged_at)\n",{"type":33,"tag":94,"props":2191,"children":2192},{"class":96,"line":27},[2193,2197,2201],{"type":33,"tag":94,"props":2194,"children":2195},{"style":117},[2196],{"type":38,"value":1356},{"type":33,"tag":94,"props":2198,"children":2199},{"style":111},[2200],{"type":38,"value":1361},{"type":33,"tag":94,"props":2202,"children":2203},{"style":117},[2204],{"type":38,"value":2205}," canonical_user_id;\n",{"type":33,"tag":94,"props":2207,"children":2208},{"class":96,"line":404},[2209],{"type":33,"tag":94,"props":2210,"children":2211},{"emptyLinePlaceholder":655},[2212],{"type":38,"value":658},{"type":33,"tag":94,"props":2214,"children":2215},{"class":96,"line":427},[2216],{"type":33,"tag":94,"props":2217,"children":2218},{"style":101},[2219],{"type":38,"value":2220},"-- Объединение с запросом когорты\n",{"type":33,"tag":94,"props":2222,"children":2223},{"class":96,"line":683},[2224,2228,2233,2237],{"type":33,"tag":94,"props":2225,"children":2226},{"style":111},[2227],{"type":38,"value":666},{"type":33,"tag":94,"props":2229,"children":2230},{"style":117},[2231],{"type":38,"value":2232}," resolved_users ",{"type":33,"tag":94,"props":2234,"children":2235},{"style":111},[2236],{"type":38,"value":164},{"type":33,"tag":94,"props":2238,"children":2239},{"style":117},[2240],{"type":38,"value":680},{"type":33,"tag":94,"props":2242,"children":2243},{"class":96,"line":696},[2244,2248],{"type":33,"tag":94,"props":2245,"children":2246},{"style":111},[2247],{"type":38,"value":689},{"type":33,"tag":94,"props":2249,"children":2250},{"style":117},[2251],{"type":38,"value":120},{"type":33,"tag":94,"props":2253,"children":2254},{"class":96,"line":717},[2255,2260,2264,2269,2273,2278,2282,2286,2290,2294,2298,2302],{"type":33,"tag":94,"props":2256,"children":2257},{"style":132},[2258],{"type":38,"value":2259},"    COALESCE",{"type":33,"tag":94,"props":2261,"children":2262},{"style":117},[2263],{"type":38,"value":243},{"type":33,"tag":94,"props":2265,"children":2266},{"style":132},[2267],{"type":38,"value":2268},"ig",{"type":33,"tag":94,"props":2270,"children":2271},{"style":117},[2272],{"type":38,"value":140},{"type":33,"tag":94,"props":2274,"children":2275},{"style":132},[2276],{"type":38,"value":2277},"canonical_user_id",{"type":33,"tag":94,"props":2279,"children":2280},{"style":117},[2281],{"type":38,"value":60},{"type":33,"tag":94,"props":2283,"children":2284},{"style":132},[2285],{"type":38,"value":183},{"type":33,"tag":94,"props":2287,"children":2288},{"style":117},[2289],{"type":38,"value":140},{"type":33,"tag":94,"props":2291,"children":2292},{"style":132},[2293],{"type":38,"value":262},{"type":33,"tag":94,"props":2295,"children":2296},{"style":117},[2297],{"type":38,"value":159},{"type":33,"tag":94,"props":2299,"children":2300},{"style":111},[2301],{"type":38,"value":164},{"type":33,"tag":94,"props":2303,"children":2304},{"style":117},[2305],{"type":38,"value":2306}," user_id,\n",{"type":33,"tag":94,"props":2308,"children":2309},{"class":96,"line":758},[2310,2314,2318,2322],{"type":33,"tag":94,"props":2311,"children":2312},{"style":132},[2313],{"type":38,"value":821},{"type":33,"tag":94,"props":2315,"children":2316},{"style":117},[2317],{"type":38,"value":140},{"type":33,"tag":94,"props":2319,"children":2320},{"style":132},[2321],{"type":38,"value":192},{"type":33,"tag":94,"props":2323,"children":2324},{"style":117},[2325],{"type":38,"value":544},{"type":33,"tag":94,"props":2327,"children":2328},{"class":96,"line":815},[2329,2333,2337],{"type":33,"tag":94,"props":2330,"children":2331},{"style":132},[2332],{"type":38,"value":821},{"type":33,"tag":94,"props":2334,"children":2335},{"style":117},[2336],{"type":38,"value":140},{"type":33,"tag":94,"props":2338,"children":2339},{"style":132},[2340],{"type":38,"value":2341},"event_name\n",{"type":33,"tag":94,"props":2343,"children":2344},{"class":96,"line":836},[2345,2349],{"type":33,"tag":94,"props":2346,"children":2347},{"style":111},[2348],{"type":38,"value":859},{"type":33,"tag":94,"props":2350,"children":2351},{"style":117},[2352],{"type":38,"value":2353}," events e\n",{"type":33,"tag":94,"props":2355,"children":2356},{"class":96,"line":853},[2357,2362],{"type":33,"tag":94,"props":2358,"children":2359},{"style":111},[2360],{"type":38,"value":2361},"  LEFT JOIN",{"type":33,"tag":94,"props":2363,"children":2364},{"style":117},[2365],{"type":38,"value":2366}," identity_graph ig \n",{"type":33,"tag":94,"props":2368,"children":2369},{"class":96,"line":877},[2370,2375,2379,2383,2387,2391,2396,2400,2404,2408,2412,2416,2420,2424,2428,2432],{"type":33,"tag":94,"props":2371,"children":2372},{"style":111},[2373],{"type":38,"value":2374},"    ON",{"type":33,"tag":94,"props":2376,"children":2377},{"style":132},[2378],{"type":38,"value":330},{"type":33,"tag":94,"props":2380,"children":2381},{"style":117},[2382],{"type":38,"value":140},{"type":33,"tag":94,"props":2384,"children":2385},{"style":132},[2386],{"type":38,"value":2081},{"type":33,"tag":94,"props":2388,"children":2389},{"style":111},[2390],{"type":38,"value":325},{"type":33,"tag":94,"props":2392,"children":2393},{"style":132},[2394],{"type":38,"value":2395}," ig",{"type":33,"tag":94,"props":2397,"children":2398},{"style":117},[2399],{"type":38,"value":140},{"type":33,"tag":94,"props":2401,"children":2402},{"style":132},[2403],{"type":38,"value":2081},{"type":33,"tag":94,"props":2405,"children":2406},{"style":111},[2407],{"type":38,"value":1899},{"type":33,"tag":94,"props":2409,"children":2410},{"style":132},[2411],{"type":38,"value":330},{"type":33,"tag":94,"props":2413,"children":2414},{"style":117},[2415],{"type":38,"value":140},{"type":33,"tag":94,"props":2417,"children":2418},{"style":132},[2419],{"type":38,"value":262},{"type":33,"tag":94,"props":2421,"children":2422},{"style":111},[2423],{"type":38,"value":325},{"type":33,"tag":94,"props":2425,"children":2426},{"style":132},[2427],{"type":38,"value":2395},{"type":33,"tag":94,"props":2429,"children":2430},{"style":117},[2431],{"type":38,"value":140},{"type":33,"tag":94,"props":2433,"children":2434},{"style":132},[2435],{"type":38,"value":339},{"type":33,"tag":94,"props":2437,"children":2438},{"class":96,"line":932},[2439],{"type":33,"tag":94,"props":2440,"children":2441},{"style":117},[2442],{"type":38,"value":1010},{"type":33,"tag":94,"props":2444,"children":2445},{"class":96,"line":951},[2446,2450],{"type":33,"tag":94,"props":2447,"children":2448},{"style":111},[2449],{"type":38,"value":114},{"type":33,"tag":94,"props":2451,"children":2452},{"style":117},[2453],{"type":38,"value":120},{"type":33,"tag":94,"props":2455,"children":2456},{"class":96,"line":995},[2457,2461,2465,2469,2473,2477,2481,2485,2489],{"type":33,"tag":94,"props":2458,"children":2459},{"style":117},[2460],{"type":38,"value":129},{"type":33,"tag":94,"props":2462,"children":2463},{"style":132},[2464],{"type":38,"value":135},{"type":33,"tag":94,"props":2466,"children":2467},{"style":117},[2468],{"type":38,"value":140},{"type":33,"tag":94,"props":2470,"children":2471},{"style":132},[2472],{"type":38,"value":145},{"type":33,"tag":94,"props":2474,"children":2475},{"style":117},[2476],{"type":38,"value":60},{"type":33,"tag":94,"props":2478,"children":2479},{"style":111},[2480],{"type":38,"value":154},{"type":33,"tag":94,"props":2482,"children":2483},{"style":117},[2484],{"type":38,"value":159},{"type":33,"tag":94,"props":2486,"children":2487},{"style":111},[2488],{"type":38,"value":164},{"type":33,"tag":94,"props":2490,"children":2491},{"style":117},[2492],{"type":38,"value":169},{"type":33,"tag":94,"props":2494,"children":2495},{"class":96,"line":1004},[2496,2500,2505,2509,2513,2517,2521,2525,2529,2533,2537,2541,2545],{"type":33,"tag":94,"props":2497,"children":2498},{"style":117},[2499],{"type":38,"value":178},{"type":33,"tag":94,"props":2501,"children":2502},{"style":132},[2503],{"type":38,"value":2504},"r",{"type":33,"tag":94,"props":2506,"children":2507},{"style":117},[2508],{"type":38,"value":140},{"type":33,"tag":94,"props":2510,"children":2511},{"style":132},[2512],{"type":38,"value":192},{"type":33,"tag":94,"props":2514,"children":2515},{"style":117},[2516],{"type":38,"value":60},{"type":33,"tag":94,"props":2518,"children":2519},{"style":132},[2520],{"type":38,"value":135},{"type":33,"tag":94,"props":2522,"children":2523},{"style":117},[2524],{"type":38,"value":140},{"type":33,"tag":94,"props":2526,"children":2527},{"style":132},[2528],{"type":38,"value":145},{"type":33,"tag":94,"props":2530,"children":2531},{"style":117},[2532],{"type":38,"value":60},{"type":33,"tag":94,"props":2534,"children":2535},{"style":111},[2536],{"type":38,"value":154},{"type":33,"tag":94,"props":2538,"children":2539},{"style":117},[2540],{"type":38,"value":159},{"type":33,"tag":94,"props":2542,"children":2543},{"style":111},[2544],{"type":38,"value":164},{"type":33,"tag":94,"props":2546,"children":2547},{"style":117},[2548],{"type":38,"value":229},{"type":33,"tag":94,"props":2550,"children":2551},{"class":96,"line":1013},[2552,2556,2560,2564,2569,2573,2577,2581,2585],{"type":33,"tag":94,"props":2553,"children":2554},{"style":132},[2555],{"type":38,"value":238},{"type":33,"tag":94,"props":2557,"children":2558},{"style":117},[2559],{"type":38,"value":243},{"type":33,"tag":94,"props":2561,"children":2562},{"style":111},[2563],{"type":38,"value":248},{"type":33,"tag":94,"props":2565,"children":2566},{"style":132},[2567],{"type":38,"value":2568}," r",{"type":33,"tag":94,"props":2570,"children":2571},{"style":117},[2572],{"type":38,"value":140},{"type":33,"tag":94,"props":2574,"children":2575},{"style":132},[2576],{"type":38,"value":262},{"type":33,"tag":94,"props":2578,"children":2579},{"style":117},[2580],{"type":38,"value":159},{"type":33,"tag":94,"props":2582,"children":2583},{"style":111},[2584],{"type":38,"value":164},{"type":33,"tag":94,"props":2586,"children":2587},{"style":117},[2588],{"type":38,"value":275},{"type":33,"tag":94,"props":2590,"children":2591},{"class":96,"line":1022},[2592,2596],{"type":33,"tag":94,"props":2593,"children":2594},{"style":111},[2595],{"type":38,"value":284},{"type":33,"tag":94,"props":2597,"children":2598},{"style":117},[2599],{"type":38,"value":2600}," resolved_users r\n",{"type":33,"tag":94,"props":2602,"children":2603},{"class":96,"line":1031},[2604,2608,2613,2617,2621,2625,2629,2633,2637,2641],{"type":33,"tag":94,"props":2605,"children":2606},{"style":111},[2607],{"type":38,"value":298},{"type":33,"tag":94,"props":2609,"children":2610},{"style":117},[2611],{"type":38,"value":2612}," users u ",{"type":33,"tag":94,"props":2614,"children":2615},{"style":111},[2616],{"type":38,"value":308},{"type":33,"tag":94,"props":2618,"children":2619},{"style":132},[2620],{"type":38,"value":2568},{"type":33,"tag":94,"props":2622,"children":2623},{"style":117},[2624],{"type":38,"value":140},{"type":33,"tag":94,"props":2626,"children":2627},{"style":132},[2628],{"type":38,"value":262},{"type":33,"tag":94,"props":2630,"children":2631},{"style":111},[2632],{"type":38,"value":325},{"type":33,"tag":94,"props":2634,"children":2635},{"style":132},[2636],{"type":38,"value":253},{"type":33,"tag":94,"props":2638,"children":2639},{"style":117},[2640],{"type":38,"value":140},{"type":33,"tag":94,"props":2642,"children":2643},{"style":132},[2644],{"type":38,"value":339},{"type":33,"tag":94,"props":2646,"children":2647},{"class":96,"line":1040},[2648,2652,2656,2660,2664],{"type":33,"tag":94,"props":2649,"children":2650},{"style":111},[2651],{"type":38,"value":410},{"type":33,"tag":94,"props":2653,"children":2654},{"style":132},[2655],{"type":38,"value":415},{"type":33,"tag":94,"props":2657,"children":2658},{"style":117},[2659],{"type":38,"value":60},{"type":33,"tag":94,"props":2661,"children":2662},{"style":132},[2663],{"type":38,"value":446},{"type":33,"tag":94,"props":2665,"children":2666},{"style":117},[2667],{"type":38,"value":451},{"type":33,"tag":34,"props":2669,"children":2670},{},[2671],{"type":38,"value":2672},"Без identity resolution когорты завышаются на 12-18% (один пользователь записывается под двумя разными ID). Эта ошибка делает метрики удержания заниженными, потому что размер когорты в знаменателе растёт, а активность на day_n остаётся той же.",{"type":33,"tag":41,"props":2674,"children":2676},{"id":2675},"мониторинг-стоимости-запросов-production-monitoring-через-information_schema",[2677],{"type":38,"value":2678},"Мониторинг стоимости запросов: production-monitoring через INFORMATION_SCHEMA",{"type":33,"tag":34,"props":2680,"children":2681},{},[2682,2684,2690],{"type":38,"value":2683},"После настройки архитектуры когорт нужна постоянная оптимизация стоимости запросов. Таблица ",{"type":33,"tag":53,"props":2685,"children":2687},{"className":2686},[],[2688],{"type":38,"value":2689},"INFORMATION_SCHEMA.JOBS",{"type":38,"value":2691}," в BigQuery показывает количество отсканированных байтов, использование slots и общую стоимость каждого запроса.",{"type":33,"tag":84,"props":2693,"children":2695},{"className":86,"code":2694,"language":88,"meta":16,"style":16},"SELECT\n  user_email,\n  query,\n  total_bytes_processed \u002F POW(10, 12) AS tb_processed,\n  (total_bytes_processed \u002F POW(10, 12)) * 5 AS cost_usd,\n  total_slot_ms \u002F 1000 \u002F 60 AS slot_minutes\nFROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT\nWHERE creation_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)\n  AND statement_type = 'SELECT'\n  AND query LIKE '%cohort_retention%'\nORDER BY total_bytes_processed DESC\nLIMIT 20;\n",[2696],{"type":33,"tag":53,"props":2697,"children":2698},{"__ignoreMap":16},[2699,2706,2714,2722,2767,2819,2855,2885,2931,2952,2974,2991],{"type":33,"tag":94,"props":2700,"children":2701},{"class":96,"line":97},[2702],{"type":33,"tag":94,"props":2703,"children":2704},{"style":111},[2705],{"type":38,"value":1019},{"type":33,"tag":94,"props":2707,"children":2708},{"class":96,"line":107},[2709],{"type":33,"tag":94,"props":2710,"children":2711},{"style":117},[2712],{"type":38,"value":2713},"  user_email,\n",{"type":33,"tag":94,"props":2715,"children":2716},{"class":96,"line":123},[2717],{"type":33,"tag":94,"props":2718,"children":2719},{"style":117},[2720],{"type":38,"value":2721},"  query,\n",{"type":33,"tag":94,"props":2723,"children":2724},{"class":96,"line":172},[2725,2730,2735,2740,2745,2749,2754,2758,2762],{"type":33,"tag":94,"props":2726,"children":2727},{"style":117},[2728],{"type":38,"value":2729},"  total_bytes_processed ",{"type":33,"tag":94,"props":2731,"children":2732},{"style":111},[2733],{"type":38,"value":2734},"\u002F",{"type":33,"tag":94,"props":2736,"children":2737},{"style":117},[2738],{"type":38,"value":2739}," POW(",{"type":33,"tag":94,"props":2741,"children":2742},{"style":132},[2743],{"type":38,"value":2744},"10",{"type":33,"tag":94,"props":2746,"children":2747},{"style":117},[2748],{"type":38,"value":60},{"type":33,"tag":94,"props":2750,"children":2751},{"style":132},[2752],{"type":38,"value":2753},"12",{"type":33,"tag":94,"props":2755,"children":2756},{"style":117},[2757],{"type":38,"value":159},{"type":33,"tag":94,"props":2759,"children":2760},{"style":111},[2761],{"type":38,"value":164},{"type":33,"tag":94,"props":2763,"children":2764},{"style":117},[2765],{"type":38,"value":2766}," tb_processed,\n",{"type":33,"tag":94,"props":2768,"children":2769},{"class":96,"line":232},[2770,2775,2779,2783,2787,2791,2795,2800,2805,2810,2814],{"type":33,"tag":94,"props":2771,"children":2772},{"style":117},[2773],{"type":38,"value":2774},"  (total_bytes_processed ",{"type":33,"tag":94,"props":2776,"children":2777},{"style":111},[2778],{"type":38,"value":2734},{"type":33,"tag":94,"props":2780,"children":2781},{"style":117},[2782],{"type":38,"value":2739},{"type":33,"tag":94,"props":2784,"children":2785},{"style":132},[2786],{"type":38,"value":2744},{"type":33,"tag":94,"props":2788,"children":2789},{"style":117},[2790],{"type":38,"value":60},{"type":33,"tag":94,"props":2792,"children":2793},{"style":132},[2794],{"type":38,"value":2753},{"type":33,"tag":94,"props":2796,"children":2797},{"style":117},[2798],{"type":38,"value":2799},")) ",{"type":33,"tag":94,"props":2801,"children":2802},{"style":111},[2803],{"type":38,"value":2804},"*",{"type":33,"tag":94,"props":2806,"children":2807},{"style":132},[2808],{"type":38,"value":2809}," 5",{"type":33,"tag":94,"props":2811,"children":2812},{"style":111},[2813],{"type":38,"value":1051},{"type":33,"tag":94,"props":2815,"children":2816},{"style":117},[2817],{"type":38,"value":2818}," cost_usd,\n",{"type":33,"tag":94,"props":2820,"children":2821},{"class":96,"line":278},[2822,2827,2831,2836,2841,2846,2850],{"type":33,"tag":94,"props":2823,"children":2824},{"style":117},[2825],{"type":38,"value":2826},"  total_slot_ms ",{"type":33,"tag":94,"props":2828,"children":2829},{"style":111},[2830],{"type":38,"value":2734},{"type":33,"tag":94,"props":2832,"children":2833},{"style":132},[2834],{"type":38,"value":2835}," 1000",{"type":33,"tag":94,"props":2837,"children":2838},{"style":111},[2839],{"type":38,"value":2840}," \u002F",{"type":33,"tag":94,"props":2842,"children":2843},{"style":132},[2844],{"type":38,"value":2845}," 60",{"type":33,"tag":94,"props":2847,"children":2848},{"style":111},[2849],{"type":38,"value":1051},{"type":33,"tag":94,"props":2851,"children":2852},{"style":117},[2853],{"type":38,"value":2854}," slot_minutes\n",{"type":33,"tag":94,"props":2856,"children":2857},{"class":96,"line":292},[2858,2862,2867,2871,2876,2880],{"type":33,"tag":94,"props":2859,"children":2860},{"style":111},[2861],{"type":38,"value":284},{"type":33,"tag":94,"props":2863,"children":2864},{"style":368},[2865],{"type":38,"value":2866}," `region-us`",{"type":33,"tag":94,"props":2868,"children":2869},{"style":117},[2870],{"type":38,"value":140},{"type":33,"tag":94,"props":2872,"children":2873},{"style":132},[2874],{"type":38,"value":2875},"INFORMATION_SCHEMA",{"type":33,"tag":94,"props":2877,"children":2878},{"style":117},[2879],{"type":38,"value":140},{"type":33,"tag":94,"props":2881,"children":2882},{"style":132},[2883],{"type":38,"value":2884},"JOBS_BY_PROJECT\n",{"type":33,"tag":94,"props":2886,"children":2887},{"class":96,"line":342},[2888,2892,2897,2902,2907,2912,2917,2922,2927],{"type":33,"tag":94,"props":2889,"children":2890},{"style":111},[2891],{"type":38,"value":348},{"type":33,"tag":94,"props":2893,"children":2894},{"style":117},[2895],{"type":38,"value":2896}," creation_time ",{"type":33,"tag":94,"props":2898,"children":2899},{"style":111},[2900],{"type":38,"value":2901},">=",{"type":33,"tag":94,"props":2903,"children":2904},{"style":117},[2905],{"type":38,"value":2906}," TIMESTAMP_SUB(",{"type":33,"tag":94,"props":2908,"children":2909},{"style":132},[2910],{"type":38,"value":2911},"CURRENT_TIMESTAMP",{"type":33,"tag":94,"props":2913,"children":2914},{"style":117},[2915],{"type":38,"value":2916},"(), INTERVAL ",{"type":33,"tag":94,"props":2918,"children":2919},{"style":132},[2920],{"type":38,"value":2921},"7",{"type":33,"tag":94,"props":2923,"children":2924},{"style":111},[2925],{"type":38,"value":2926}," DAY",{"type":33,"tag":94,"props":2928,"children":2929},{"style":117},[2930],{"type":38,"value":1010},{"type":33,"tag":94,"props":2932,"children":2933},{"class":96,"line":27},[2934,2938,2943,2947],{"type":33,"tag":94,"props":2935,"children":2936},{"style":111},[2937],{"type":38,"value":379},{"type":33,"tag":94,"props":2939,"children":2940},{"style":117},[2941],{"type":38,"value":2942}," statement_type ",{"type":33,"tag":94,"props":2944,"children":2945},{"style":111},[2946],{"type":38,"value":534},{"type":33,"tag":94,"props":2948,"children":2949},{"style":368},[2950],{"type":38,"value":2951}," 'SELECT'\n",{"type":33,"tag":94,"props":2953,"children":2954},{"class":96,"line":404},[2955,2959,2964,2969],{"type":33,"tag":94,"props":2956,"children":2957},{"style":111},[2958],{"type":38,"value":379},{"type":33,"tag":94,"props":2960,"children":2961},{"style":117},[2962],{"type":38,"value":2963}," query ",{"type":33,"tag":94,"props":2965,"children":2966},{"style":111},[2967],{"type":38,"value":2968},"LIKE",{"type":33,"tag":94,"props":2970,"children":2971},{"style":368},[2972],{"type":38,"value":2973}," '%cohort_retention%'\n",{"type":33,"tag":94,"props":2975,"children":2976},{"class":96,"line":427},[2977,2981,2986],{"type":33,"tag":94,"props":2978,"children":2979},{"style":111},[2980],{"type":38,"value":433},{"type":33,"tag":94,"props":2982,"children":2983},{"style":117},[2984],{"type":38,"value":2985}," total_bytes_processed ",{"type":33,"tag":94,"props":2987,"children":2988},{"style":111},[2989],{"type":38,"value":2990},"DESC\n",{"type":33,"tag":94,"props":2992,"children":2993},{"class":96,"line":683},[2994,2999,3004],{"type":33,"tag":94,"props":2995,"children":2996},{"style":111},[2997],{"type":38,"value":2998},"LIMIT",{"type":33,"tag":94,"props":3000,"children":3001},{"style":132},[3002],{"type":38,"value":3003}," 20",{"type":33,"tag":94,"props":3005,"children":3006},{"style":117},[3007],{"type":38,"value":451},{"type":33,"tag":34,"props":3009,"children":3010},{},[3011,3013,3019],{"type":38,"value":3012},"Этот запрос выводит top запросы к таблицам когорт за последние 7 дней, отсортированные по стоимости. Если какая-то панель dashboard запускается 500 раз в день и сканирует по 80GB каждый раз (значит, отсутствует partition filter), это генерирует 500 × 80GB × 5$\u002FTB = 200$ расходов в день. Добавив ",{"type":33,"tag":53,"props":3014,"children":3016},{"className":3015},[],[3017],{"type":38,"value":3018},"WHERE cohort_date >= CURRENT_DATE() - 30",{"type":38,"value":3020}," в query панели, вы снижаете стоимость до 6$.",{"type":33,"tag":34,"props":3022,"children":3023},{},[3024],{"type":33,"tag":458,"props":3025,"children":3026},{},[3027],{"type":38,"value":3028},"Production checklist:",{"type":33,"tag":3030,"props":3031,"children":3034},"ul",{"className":3032},[3033],"contains-task-list",[3035,3055,3077,3086,3095,3112],{"type":33,"tag":3036,"props":3037,"children":3040},"li",{"className":3038},[3039],"task-list-item",[3041,3046,3048,3053],{"type":33,"tag":3042,"props":3043,"children":3045},"input",{"disabled":655,"type":3044},"checkbox",[],{"type":38,"value":3047}," Все таблицы когорт разбиты по ",{"type":33,"tag":53,"props":3049,"children":3051},{"className":3050},[],[3052],{"type":38,"value":1878},{"type":38,"value":3054}," partition?",{"type":33,"tag":3036,"props":3056,"children":3058},{"className":3057},[3039],[3059,3062,3064,3069,3070,3075],{"type":33,"tag":3042,"props":3060,"children":3061},{"disabled":655,"type":3044},[],{"type":38,"value":3063}," ",{"type":33,"tag":53,"props":3065,"children":3067},{"className":3066},[],[3068],{"type":38,"value":1993},{"type":38,"value":464},{"type":33,"tag":53,"props":3071,"children":3073},{"className":3072},[],[3074],{"type":38,"value":2000},{"type":38,"value":3076}," кластеризованы?",{"type":33,"tag":3036,"props":3078,"children":3080},{"className":3079},[3039],[3081,3084],{"type":33,"tag":3042,"props":3082,"children":3083},{"disabled":655,"type":3044},[],{"type":38,"value":3085}," dbt incremental job запускается ежедневно?",{"type":33,"tag":3036,"props":3087,"children":3089},{"className":3088},[3039],[3090,3093],{"type":33,"tag":3042,"props":3091,"children":3092},{"disabled":655,"type":3044},[],{"type":38,"value":3094}," Materialized view ограничена 90-дневным окном?",{"type":33,"tag":3036,"props":3096,"children":3098},{"className":3097},[3039],[3099,3102,3104,3110],{"type":33,"tag":3042,"props":3100,"children":3101},{"disabled":655,"type":3044},[],{"type":38,"value":3103}," Query'и dashboard содержат фильтр ",{"type":33,"tag":53,"props":3105,"children":3107},{"className":3106},[],[3108],{"type":38,"value":3109},"WHERE cohort_date >= ...",{"type":38,"value":3111},"?",{"type":33,"tag":3036,"props":3113,"children":3115},{"className":3114},[3039],[3116,3119,3121,3126],{"type":33,"tag":3042,"props":3117,"children":3118},{"disabled":655,"type":3044},[],{"type":38,"value":3120}," Еженедельный отчёт о затратах выполняется через ",{"type":33,"tag":53,"props":3122,"children":3124},{"className":3123},[],[3125],{"type":38,"value":2875},{"type":38,"value":3111},{"type":33,"tag":34,"props":3128,"children":3129},{},[3130],{"type":38,"value":3131},"Когда архитектура когорт построена правильно, анализ удержания становится production-ready: 100M событий в день, 5 секунд времени запроса, 10 долларов ежемесячных расходов на вычисления. Однако эта архитектура требует first-party identity resolution, стандартизированной схемы событий и дисциплины dbt pipeline — именно поэтому retention engineering — это платформная функция, а не",{"type":33,"tag":3133,"props":3134,"children":3135},"style",{},[3136],{"type":38,"value":3137},"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":123,"depth":123,"links":3139},[3140,3143,3144,3145,3146],{"id":43,"depth":107,"text":46,"children":3141},[3142],{"id":474,"depth":123,"text":477},{"id":1290,"depth":107,"text":1293},{"id":1854,"depth":107,"text":1857},{"id":2049,"depth":107,"text":2052},{"id":2675,"depth":107,"text":2678},"markdown","content:ru:data:cohort-tablitsa-arkhitektura-masshtabirovanie-analiza-uderzhaniia-v-produkcii.md","content","ru\u002Fdata\u002Fcohort-tablitsa-arkhitektura-masshtabirovanie-analiza-uderzhaniia-v-produkcii.md","ru\u002Fdata\u002Fcohort-tablitsa-arkhitektura-masshtabirovanie-analiza-uderzhaniia-v-produkcii","md",1782079495319]