一个快速的谷歌搜索想出了答案:
许多操作使用面向列的方法更有效。特别是,需要从特定列访问一系列值的操作要快得多。如果列中的所有值都具有相同的大小(按照设计,在 kdb 中这是真的),事情会变得更好。这种类型的访问模式是使用 q 和 kdb 的应用程序的典型。
为了具体说明,让我们检查一列 64 位浮点数:
q).Q.w[] `used
108464j
q)t: ([] f: 1000000 ? 1.0)
q).Q.w[] `used
8497328j
q)
如您所见,保存一百万个 8 字节值所需的内存仅略高于 8MB。这是因为数据按顺序存储在数组中。为了澄清,让我们创建另一个表:
q)u: update g: 1000000 ? 5.0 from t
q).Q.w[] `used
16885952j
q)
t 和 u 都共享列 f。如果 q 按行组织其数据,则内存使用量将再增加 8MB。确认这一点的另一种方法是查看 kh
现在让我们看看当我们将表写入磁盘时会发生什么:
q)`:t/ set t
`:t/
q)\ls -l t
"total 15632"
"-rw-r--r-- 1 kdbfaq staff 8000016 May 29 19:57 f"
q)
16 字节的开销。显然,所有数字都按顺序存储在磁盘上。效率是关于避免不必要的工作,在这里我们看到 q 正是在读写列时需要做的事情——不多也不少。
好的,所以这种方法是节省空间的。这种数据布局如何转化为速度?
如果我们要求 q 对所有 100 万个数字求和,那么将整个列表紧密地打包在内存中比面向行的组织具有巨大的优势,因为我们在内存层次结构的每个阶段都会遇到更少的未命中。避免缓存未命中和页面错误对于提高机器性能至关重要。
此外,对内存中的一长串数字进行数学运算是现代 CPU 指令集具有特殊功能需要处理的问题,包括在不久的将来需要预取数组元素的指令。尽管这些功能最初是为了提高 PC 多媒体性能而创建的,但事实证明它们也非常适合统计数据。此外,局部性和 CPU 特性的相同协同作用使面向列的系统能够比索引搜索(伴随着分支预测失败)更快地执行线性搜索(例如,在未索引列上的 where 子句中),达到惊人的行数。
来源(S):http ://www.kdbfaq.com/kdb-faq/tag/why-kdb-fast