先交代一下背景。
2021 年我从数据分析师转去做 BI 实施,前前后后跟了四个项目:一家连锁餐饮(大概 260 家门店)、一家做工业配件的贸易商、一个 SaaS 后台的运营看板,还有一家跨境电商。四个里面有三个,上线半年后日活掉到个位数。不全是工具的问题,是我一开始的选型思路就是歪的。
那时候我的判断标准是:谁家图表好看、谁家上手快、谁家便宜。现在回头看,这三条基本全是次要的。
真正让我翻车的是第二个项目。客户财务总监要一张月度经营分析表,我把 40 多个指标全做成可自由拖拽的 Tableau 仪表板,觉得灵活就是好。三个月后出事了,两个部门算出来的“毛利率”差了 3.7 个百分点——一个含运费,一个不含。财务总监当着老板的面问我,到底哪个是真的。我解释了十几分钟,越解释越像在找借口。当晚我把那张表的计算字段导出来数了数,17 个,名字分别是毛利率、毛利率2、毛利率_最终、毛利率_fix……
那天之后我慢慢形成一个判断,可能有点绝对,但我现在确实这么用:企业里的报表分两类,考核型和探索型,这两种东西不该用同一种方式做。
考核型是给财务、给老板、要签字的那种。口径固定,数字要能对得上账,要能顺着一个数追到源头的每一行。它可能一个月只更新一次,但错一个数就是事故。这种报表的要害是两个字,可审计。
探索型是给分析师自己找原因用的。今天想按渠道切,明天想按时间段切,后天想看看是不是某个 SKU 拖累的。这种报表的要害是“快”和“自由”,探索完就扔,不需要留痕。
我见过最多的失败就是这两类混着做:拿 Tableau 去顶月度的、要跟财务对账的经营报表,或者拿 Power BI 这种强模型化的东西去应付每天都在变的临时探索。前者必然口径漂移,后者必然 DAX 写到崩溃,然后开始骂工具。
引擎层面到底差在哪
这三个工具的底层差别,比 UI 差别大得多,而且直接决定了你什么场景能用它。
Power BI 走的是 VertiPaq 引擎(老名字叫 xVelocity),列存加字典编码加位压缩,官方文档里提过典型压缩率 5 到 10 倍。我实测过一份 2.3 亿行的门店流水,Parquet 原始文件 6.8 GB,导进去之后内存占用 890 MB 左右,那个瞬间是挺爽的。但这里有个坑,字符串列基数一高,压缩率立刻崩。同一个模型里我留着“订单号”这种基本唯一的列,内存从 890 MB 直接涨到 4.1 GB,删掉又回来了。所以 Power BI 的第一条铁律不是 DAX 写得多优雅,是先看列基数,能删的列一定删。
Tableau 的引擎是 Hyper,2016 年收购的德国团队做的,前身是波茨坦大学的 Hyrise 项目,2017 年 Tableau 10.5 开始成为默认抽取格式。列存加内存映射,.hyper 文件直接躺在磁盘上,边读边查。Tableau 真正的王牌其实是 VizQL,拖拽的响应手感确实好,同行里我没见过更好的。但它的建模能力是弱项,表之间的关系全靠手动定义,也不强制你建星型模型,这就把口径治理这件事整个甩给了使用者。
Qlik Sense 走的是第三条路,关联引擎 Associative Engine。它把每一列里不同的值做符号化编码,官方一直对外说压缩能到 10 倍左右。好处是关联分析确实顺手,随便点一个值,全模型相关的都跟着高亮;代价是它要求表尽量都进同一个内存结构,数据量一大就得靠 QVD 分层做预处理,否则刷新时间会很难看。
| 维度 | Power BI | Tableau | Qlik Sense |
|---|---|---|---|
| 查询引擎 | VertiPaq,列存 + 字典编码 | Hyper,列存 + 内存映射 | 符号化关联引擎 |
| 是否强制星型模型 | 基本强制,关系混乱会报错 | 不强制 | 不强制,靠关联 |
| 计算语言 | DAX,学习曲线最陡 | 计算字段,类 Excel 思维 | 脚本 + 表达式,中等 |
| 语义层能力 | Tabular 模型,较强,能当半个语义层用 | 较弱 | 中等 |
| 授权参考 | Pro $14/用户/月,PPU $24 | Creator $75/用户/月 | 大致 $20–40/用户/月 |
| 数据集上限 | Pro 1 GB,Premium/PPU 100 GB | 看底层数据库 | 看内存 |
价格这里说明一下,是写这篇文章时的挂牌行情,这几家基本每年都在动,以官网为准。但有个规律挺稳的:Power BI 按人头便宜、按容量贵,Premium F64 那一档年费是几万美元量级;Tableau 反过来,人头就贵,且 Creator 之外还有 Viewer、Explorer 的价差;Qlik 看你怎么签,嵌入式授权和内部使用完全是两个价。
一个绕不过去的问题:为什么你的报表没人看
我后来统计过第三个项目,上线时有 87 张报表,三个月后打开率超过每周一次的只有 9 张。不是做得丑,是这 78 张大多属于“有人问过一句话,我就顺手做了一张”。
解决这件事的办法很土,但有效:先建指标字典,再做报表。
具体怎么做,我现在的流程是这样:
- 把所有指标名列成一张表,一列指标名、一列口径描述、一列负责人、一列最后修改时间。
- 口径描述必须写到能让一个新人照着 SQL 复现的程度,比如“毛利率 =(不含税销售额 - 商品成本)/ 不含税销售额,不含运费和平台佣金”。
- 每个指标指定一个业务负责人,改口径必须这个人点头,不能是分析师自己改。
- 在 BI 工具里,指标只允许存在于语义层/模型层,不允许在单个报表里新建计算字段。这一条是最难的,但也是最有用的。
- 报表上线前拿字典对一遍,对不上的直接打回。
第 4 条我执行得最狠。Power BI 里就是所有度量值集中在模型层,报表页只拖不改;Tableau 里就是尽量用已发布数据源(Published Data Source),别用本地提取;Looker 那套 LookML 天然就是干这个的,所以它在口径治理这件事上确实有先天优势,Google 当年花 26 亿美元收它不是为了图表。
刷新慢这件事,九成是模型问题不是引擎问题
遇到最多的一类求助是“数据集刷新要三个多小时”。
先别急着换工具,先看三件事:列基数、日期时间列、刷新策略。
列基数前面说过了,重复一遍,能删的列马上删。
日期时间列是个特别常见的坑。Power BI 里一个 DateTime 类型列,底层是当两个列存的,拆成单独的 Date 列和 Time 列之后,压缩效果通常会好一截,sqlbi 那两个意大利人(Marco Russo 和 Alberto Ferrari)写过这个,我实测大概省 20% 到 35% 的内存,看你时间部分的粒度。如果业务根本不需要精确到秒,直接拆。
刷新策略就是增量刷新。步骤我说细一点,因为参数名大小写敏感,很多人卡在这:
- 在 Power Query 里建两个 DateTime 参数,名字必须叫 RangeStart 和 RangeEnd,大小写不能错。
- 在事实表的筛选步骤里加上条件:日期列 >= RangeStart 并且 < RangeEnd。
- 发布到 Premium 或 PPU 工作区(注意,Pro 不支持增量刷新,这是硬门槛)。
- 在数据集设置里打开增量刷新,历史上限设成比如 3 年,增量设成 7 天。
- 加一个只刷新增量的计划,比如每小时一次;再留一个每周的全量刷新兜底。
这五步做完,我们那个连锁餐饮的项目从原来 2 小时 40 分的全量刷新降到了 4 分半。但有个前提,数据源那边得支持按时间过滤,如果是那种只能全量拉取的 API,这条路走不通,得先在中间加一层落地表。
最后说点不太好听的
工具选型这件事,我觉得大部分人问的问题就错了。问“Power BI 和 Tableau 哪个好”,跟问“锤子和扳手哪个好”差不多,答案是看你手上这个是什么活儿。
我现在给别人的建议顺序是这样的:先确定这张报表是考核型还是探索型;考核型的先解决指标字典和语义层,工具放最后;探索型的谁快用谁,别纠结,三个月后可能就换了;预算有限、团队 DAX 学得动、又需要强制模型规范的,Power BI 的性价比目前还是最能打的;纯粹给人看、给客户看、对视觉要求高的,Tableau 的手感确实值那个价;如果是做嵌入式分析往外卖,那 Qlik 和 Looker 的路子要单独算一笔账。
有件事我到现在也没完全想明白。我们那个日活掉到个位数的项目,重构之后报表从 87 张减到 11 张,日活反而涨了三倍。到底是工具选对了,还是我们终于想清楚了要回答什么问题。可能后者的成分更大一点。