你排的那一队,凭什么总是最慢的
- 作者:Bougie
- 创建于:2026-10-16
上周在超市,我排了七分钟。隔壁那队换了四拨人。
我当时的结论是"我运气差",并且非常确信这一点——因为这种事不是第一次发生了。后来我把这个场景写成了代码,跑了 20 万个人,发现了一件让人不太舒服的事:这件事跟运气一点关系都没有,它是默认选项。

下面所有数字都来自我写的一个离散事件模拟器:到达间隔和服务时间都按指数分布抽样(这是排队论里最"随缘"的假设,也是现实里最接近的),Node v24.16.0,本机 Linux x86_64,每轮 15 万到 20 万人,丢弃前 10%~15% 的预热样本。不涉及网络,只有 CPU 和内存。
基准场景:5 个服务台,每人平均服务 60 秒,平均每 14.29 秒来一个人。到达率 4.20 人/分,总服务率 5.00 人/分,利用率 ρ = 0.84。就是你周末下午那家超市。
# 一、"另一队更快"不是运气差,是默认选项
先做一个最朴素的测量:站在队伍里,看过去 90 秒每条队各服务了几个人。
随机挑一个时刻、随机挑一条队,69.14% 的时刻,至少有一条队比它服务得多。
那是不是因为慢的队里挤了更多人?我把所有正在等待的人按他们所在的队分组,再按"这队最近 90 秒的进展"从快到慢排序:
| 按最近 90 秒进展排名 | 挤着全场多少等待者 |
|---|---|
| 最快那条队 | 21.20% |
| 第 2 | 20.57% |
| 第 3 | 19.21% |
| 第 4 | 19.96% |
| 最慢那条队 | 19.06% |
几乎是均匀的。换成"随机挑一个正在排队的人",答案也只是从 69.14% 变成 69.36%——差别可以忽略。慢队里并没有真的挤着更多人,因为五条队在统计上完全一样,"最慢"只是最近 90 秒的一次随机波动,下一分钟就换人了。
那 69% 这个数字是怎么来的?答案很无聊:五条队里,你恰好是跑得最快的那条,本来就是小概率事件。不是运气,是组合学。
具体一点:n=5 时,"过去 90 秒完成的人数严格多于其他所有队"——也就是你真的是全场最快那条——只占 12.75% 的时刻;"至少不比别人慢"(含并列)占 30.6%。剩下 69.4% 的时刻,你抬头就能找到一条比你快的队。
真正让这个数字变大的是你看的时机。
现实里没有人匀速抬头。人的抬头规律大致是:自己这条队不动的时候,才去看别人。我把这个行为写进模拟——"只有在我这条队过去 20 秒一个人都没走时,我才抬头":
| 队列数 n | 随机时刻随机挑一条队 | 随机挑一个排队的人 | 只在自己卡住时抬头 |
|---|---|---|---|
| 2 | 36.44% | 36.73% | 42.87% |
| 3 | 53.33% | 53.46% | 60.85% |
| 5 | 69.14% | 69.36% | 76.74% |
| 8 | 79.02% | 79.19% | 85.42% |
从 69.36% 涨到 76.74%。而且这类"我自己卡住了"的时刻,占掉你整个等待时间的 75.79%——你四分之三的排队时间都在这种状态里,所以你四分之三的印象都是"别人在动,我不动"。
最后一层是记忆。随机选一条队时,等待时间的分布是这样:
p10 = 0.0 秒
p50 = 185.9 秒
p90 = 762.4 秒
p99 = 1592.6 秒
max = 2760.9 秒
最慢的那位比最快的那位多等了 46.02 分钟,而他们做的完全是同一件事、排的是同一种队。等最久的那 20% 平均等了 869.1 秒(14.5 分钟),最快的那 20% 平均只等了 1.2 秒。
你不会记得那 1.2 秒。你记得的是 14.5 分钟,而且你会把它当成"常态"。

# 二、蛇形队:看起来更长,实际快 85%
如果说上面那节是"为什么你的主观感受不可信",那这节是"有一个简单的改造能让所有人都变快"。
同样的 5 个服务台、同样的 4.20 人/分,只改一件事:把 5 条队合并成 1 条蛇形队,谁先到谁先上,哪个窗口空了就叫下一个。
| 排队方式 | 平均等待 | 标准差 | p50 | p95 | p99 | 最坏 | 基尼系数 |
|---|---|---|---|---|---|---|---|
| 多队列(随机选一条) | 312.3s | 362.9 | 190.5s | 1065.2s | 1605.4s | 2900.4s | 0.58 |
| 多队列(选最短的) | 83.0s | 100.8 | 49.4s | 286.1s | 452.3s | 1203.0s | 0.60 |
| 单队列(蛇形) | 44.7s | 62.7 | 17.8s | 177.5s | 269.3s | 506.6s | 0.67 |
蛇形队对比随机选队:平均值 -85.69%,标准差 -82.73%,p95 -83.34%,p99 -83.23%,最坏情况 -82.53%。
几乎不用等(小于 1 秒)的人占比,从 16.51% 涨到 37.26%。
道理不难:多队列里,最典型的事故是某个窗口空着,而它那条队没人——因为你一旦选了队就被锁死了,隔壁那位买了 47 件东西,你的窗口已经空转了两分钟,你也只能看着。蛇形队消灭了这种"有人没事干同时有人没事干"的浪费。
但这里有个必须说清楚的副作用:基尼系数从 0.58 升到了 0.67。
蛇形队让"运气"变得更值钱了。37.26% 的人一秒钟都不用等,而剩下的人相对均值更惨——p95/p50 的比值从 5.59 涨到 9.98。所以蛇形队里排在尾部的人会觉得"这制度不公平",而他们的感觉在相对意义上是对的:他们确实比多队列时代绝对快得多(269.3s vs 1605.4s 的 p99),但他们的参照系变成了旁边那些一秒钟都没等的人。

这也是为什么银行和机场爱用蛇形队,而超市不用——不是超市不懂,是购物车塞不进蛇形通道,而且超市靠"你一眼就能数出前面有几个人"来安抚你。蛇形队把这条信息拿走了:你只能看到一条望不到头的长龙,尽管它前进得比谁都快。
# 三、ρ 从 0.5 涨到 0.98,等待涨了 157 倍
这节是给所有做容量规划的人的。
还是 5 个服务台、服务均值 60 秒,只改到达速率:
| 利用率 ρ | 到达间隔 | 平均等待 | p95 | 最坏 |
|---|---|---|---|---|
| 0.50 | 24.00s | 3.2s | 23.1s | 208.1s |
| 0.60 | 20.00s | 7.3s | 47.5s | 253.4s |
| 0.70 | 17.14s | 14.8s | 80.0s | 308.1s |
| 0.80 | 15.00s | 34.2s | 149.7s | 478.4s |
| 0.90 | 13.33s | 92.7s | 316.4s | 1015.0s |
| 0.95 | 12.63s | 217.0s | 818.4s | 2122.6s |
| 0.98 | 12.24s | 501.0s | 1427.7s | 2225.4s |
ρ 从 0.5 涨到 0.98,不到一倍。平均等待从 3.2 秒涨到 501.0 秒,157 倍。
而且这条曲线最陡的地方在最右边:0.90 → 0.95 这五个百分点,等待翻了 2.3 倍;0.95 → 0.98 这三个百分点,又翻了 2.3 倍。
所以"下午三点银行开一个窗口也够用,五点半开五个窗口还是挤"不是错觉——下午三点 ρ 可能是 0.5,五点半是 0.9,这两者之间的差距不是 1.8 倍,是 29 倍。同样,"再加一个窗口就好了"在 ρ 已经 0.95 的时候是最有效的干预,在 ρ=0.5 的时候几乎没用。

# 四、"10 件以下"快通道,是个精心设计的陷阱
这条标志牌几乎每家超市都有。我用它做了个实验。
假设服务时间 = 20 秒 + 2.5 秒 × 件数。60% 的人是小篮子(1–10 件,平均服务 33.8 秒),40% 的人是大车(11–60 件,平均服务 108.7 秒)。两个收银台,总 ρ = 0.85。
先算笔账,不用模拟:
快通道负载 = 0.6 × λ × 33.8 秒 = 0.54
普通道负载 = 0.4 × λ × 108.7 秒 = 1.16 ← 大于 1
普通道的负载是 1.16,意味着它每小时能处理的量小于每小时来的量。这个队会无限增长,永远清不空。
模拟证实了这一点。快通道确实很爽(小篮子平均只等 18.2 秒),但大车的等待是这样发散的:
| 第 N 位顾客到达时 | 最近 500 位大车的平均等待 |
|---|---|
| 1000 | 4970.3s |
| 2000 | 9114.9s |
| 4000 | 22282.4s |
| 6000 | 35359.7s |
| 8000 | 49524.9s |
到第 8000 人时,推大车的人平均要等 13.8 小时。这不是"比较慢",这是系统在发散。
问题不在"快通道"这个想法,在切得太随意。快通道的本质是"按服务时间分桶",而分桶就意味着把本来共享的容量切成几块互相借不到的蛋糕。只要切得不对,其中一块必然过载。
我给它一个公平的机会:开 3 个收银台,其中 1 条快通道 + 2 条普通道(这样两条普通道各担 0.58,跟快通道的 0.54 基本持平):
| 方案 | 全体 | 小篮子 | 大车 | 最坏 |
|---|---|---|---|---|
| [C] 三条通用道 | 37.1s | 36.9s | 37.3s | 521.9s |
| [D] 1 快 + 2 普通 | 36.6s | 21.0s | 59.8s | 863.9s |
负载配平之后快通道终于不是灾难了:小篮子快 43.11%,大车慢 60.43%,全体快 1.21%。
看清这个结构:快通道从来不是在"提升效率",它是在重新分配痛苦——从 60% 的人身上拿走 43% 的等待,加到 40% 的人身上。全体只赚了 1.21%,这 1.21% 还是因为分桶略微降低了服务时间的方差。它流行的真正原因是那 60% 的人会投票。

# 五、波动从哪来,就从哪治
这是整篇文章里我最想留下的一条。
同样是 5 个服务台、ρ = 0.84、蛇形队,只改"随机性来自哪里":
| 到达 | 服务 | 平均等待 | p95 | 最坏 |
|---|---|---|---|---|
| 随机 | 随机(M/M/5) | 48.0s | 191.9s | 647.9s |
| 固定 | 随机(D/M/5) | 18.3s | 90.0s | 290.0s |
| 随机 | 固定(M/D/5) | 24.5s | 92.7s | 247.1s |
| 固定 | 固定(D/D/5) | 0.0s | 0.0s | 0.0s |
| 随机 | 均匀 50~70 秒 | 24.8s | 94.3s | 256.4s |
两件事:
一,让到达变规律(48.0s → 18.3s)比让服务变规律(48.0s → 24.5s)更管用。 这直接解释了预约制为什么有效:你没让医生变快,你只是让病人不再一窝蜂地来。
二,两边都固定,等待是 0。 不是"趋近于 0",是精确的 0——14.29 秒来一个人,每人服务 60 秒,5 个窗口轮流接,第 k 个窗口接第 k、k+5、k+10… 位顾客,间隔 71.43 秒 > 60 秒,永远追不上。
再看单服务台、ρ = 0.8 时,服务时间的波动本身值多少钱:
| 服务时间分布 | 平均等待 | p95 |
|---|---|---|
| 指数分布(最随缘) | 232.0s | 812.1s |
| 常数 60 秒 | 116.6s | 383.6s |
| 均匀 30~90 秒 | 126.5s | 423.4s |
| 均匀 50~70 秒 | 117.6s | 387.6s |
| 双峰(一半 20s 一半 100s) | 168.1s | 556.0s |
232.0 / 116.6 = 1.99,正好是 2。这不是巧合,M/M/1 的排队时间恰好是 M/D/1 的两倍——排队论里少有的一个漂亮结论。
关键是倒数第二行:你不需要真的把服务时间压成常数。只要从"有时 20 秒有时 100 秒"变成"都在 50~70 秒之间",等待就从 168.1 秒掉到 117.6 秒,几乎摸到了理论下限。抹平长尾,比压缩平均值划算得多。
我二分查了一下这个"抹平波动"到底值多少提速:让服务时间保持指数分布、只压缩它的均值,要多快才能追上"波动全消"的效果?答案是 52.06 秒——也就是把服务时间的波动彻底消除,效果等价于让每个人平均快 13.23%,而且不需要多花一分钱。
放到真实场景:一家店与其重金上更快的收银系统,不如先消灭"偶尔遇到一个要核对价格的、要退货的、要找会员码的"。那几个极端值制造的长尾,比平均速度重要得多。
# 六、加一个窗口,还是让窗口快 20%?
ρ = 0.84 的 5 个服务台。你手上有一笔预算,可以让总容量提升 20%。两条路:
| 方案 | 平均等待 | p50 | p95 | 最坏 |
|---|---|---|---|---|
| 基准:5 台,ρ=0.84 | 45.5s | 16.7s | 180.4s | 547.8s |
| 加一台:6 台,ρ=0.70 | 11.1s | 0.0s | 62.0s | 309.8s |
| 提速 20%:5 台,ρ=0.70 | 12.3s | 0.0s | 66.5s | 231.0s |
| 两者都做:ρ=0.58 | 3.4s | 0.0s | 24.2s | 163.5s |
两条路都把 ρ 从 0.84 降到 0.70,效果也几乎一样:花 20% 的资源,等待时间降了约 75%。 这就是第三节那条非线性曲线的正向用法——你在悬崖上往下退一小步,收益是巨大的。
加一台略优于提速 20%(11.1s vs 12.3s),因为 6 台共享一条队的"池化"效果比 5 台更好。但差别只有 1.2 秒,真正重要的信息是:别在 ρ 已经很低的时候再加人。 ρ = 0.58 的"两者都做"只把平均等待从 11.1 秒降到 3.4 秒,性价比远不如第一次那 20%。

# 七、一个不需要模拟就能知道的公式
最后给一个能在脑子里跑的工具,Little 法则:
L = λ · W
系统里的平均人数 = 到达率 × 平均停留时间。我在模拟里验证了一次:时间平均系统内人数 8.05 人,到达率 4.22 人/分,平均停留 114.5 秒(1.91 分),λW = 8.05,误差 0.00%。
它简单得不像话,但它的威力在于它跟到达分布、服务分布、队列结构全都无关。所以你可以用它反过来查自己:
- 收银台前平均站着 8 个人,每人平均待 2 分钟 → 每分钟必须有 4 个人被服务完。做不到,队就会一直变长。
- 你想把停留时间砍一半,在到达率不变的前提下,系统里的人数就必须砍一半——没有第三条路。
- 客服说"我们积压了 300 个工单",你知道每周新进 100 个 → 平均处理时长是 3 周。不用看任何报表。
排队系统里绝大多数直觉都是错的,但这条不是。
# 八、一份清单
- "另一队更快"是组合学,不是运气。 5 条队时 69.14% 的时刻你落后于至少一条队;如果你只在自己卡住时抬头,是 76.74%,而这类时刻占你等待时间的 75.79%。
- 你记住的是尾部。 随机选队时 p50 是 185.9 秒,最坏是 2760.9 秒,差 46 分钟,而原因只是"选了那条队"。
- 能合并就合并。 5 条队合成一条,平均等待 -85.69%,标准差 -82.73%。这是全表性价比最高的一行。
- 蛇形队让"运气"更值钱。 基尼系数 0.58 → 0.67,37.26% 的人一秒不用等,剩下的人相对更惨。它更快,但不一定让人觉得更公平。
- ρ 超过 0.8 之后,每一次增量都很贵。 0.5 → 0.98 不到一倍,等待 157 倍。
- 分桶要按负载切,不要按人数切。 "10 件以下"把我模拟里的普通道切成了负载 1.16 的死局。
- 先治波动,再治速度。 抹平服务时间的长尾等价于免费提速 13%;让到达变规律(预约制)比让服务变规律更管用。
- 在悬崖边上加容量最划算。 ρ 0.84 → 0.70 花 20% 资源换 75% 的等待下降;ρ 0.70 → 0.58 只有 69%。
- 记不住别的就记 L = λW。 它对任何排队系统都成立,包括你的收件箱。
回到开头那七分钟。我现在知道那七分钟里大概有五分半我是"卡住"状态,而在这五分半里我看隔壁,有 76.74% 的概率会觉得它在动。
排队的痛苦从来不是那 312 秒,是"我本可以不排这么久"的怀疑。蛇形队解决的其实是后半件事——它把"选错队"这个选项从游戏里删掉了。你还是可能等很久,但你已经没有可以责怪的自己了。