我听过很多人在谈论KDB几乎没时间处理数百万行。为什么这么快?是因为数据都是在内存中组织的吗?
另一件事是,有替代品吗?任何大型数据库供应商都在内存数据库中提供?
答案 0 :(得分:15)
快速 Google搜索提出了答案:
使用面向列的方法,许多操作更有效。特别是,需要从特定列访问一系列值的操作要快得多。如果列中的所有值都具有相同的大小(在设计中,在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。确认这一点的另一种方法是看看k.h。
现在让我们看看当我们将表写入磁盘时会发生什么:
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功能的相同协同作用使得面向列的系统能够比索引搜索(及其伴随的分支预测失败)更快地执行线性搜索(例如,在未编制索引的列中的子句中),直到惊人的行数。
答案 1 :(得分:2)
至于速度,内存的东西确实发挥了很大的作用,但还有其他一些东西,从磁盘快速读取hdb,splaying等。从个人经验我可以说,你可以从c ++获得相当不错的速度,如果你想要的话写那么多代码。使用kdb,你可以得到所有这些以及更多。
关于速度的另一件事是编码的速度。陡峭的学习曲线,但一旦你得到它,复杂的问题可以在几分钟内编码。 您可以在内存数据库中查看onetick或google的替代方案
答案 2 :(得分:1)
kdb很快,但确实很昂贵。另外,学习Q也很痛苦。有很多选择,例如DolphinDB,Quasardb等。