3

我在 ~10MB .csv 文件中保存了大约 100GB 的数据。如何优化对该数据的数千次查询的查找速度?具体来说,我不知道要考虑哪些技术或如何估计相对性能。

每个文件对于一个日期都是唯一的,并且包含多个人的数据,例如:

...
2005-07-03, "Daffy Duck", ...
2005-07-03, "Daffy Duck", ...
2005-07-03, "Mickey Mouse", ...
2005-07-03, "Mickey Mouse", ...
...

我想为数千个日期/名称对提取与给定日期/名称对应的所有信息。等效的 SQL 查询将是SELECT * FROM myDB WHERE Date='2005-07-03' AND Name='Mickey Mouse'.

目前我还没有将数据加载到数据库中。为了执行我的“查询”,我找到了适当的日期文件并按我正在寻找的名称过滤这些行。将数据存储在关系数据库、noSQL 数据库或任何其他方式中是否会获得性能改进?如果是这样,为什么和多少?

4

4 回答 4

10
于 2012-11-28T19:29:44.463 回答
5

我要站在魔鬼的拥护者的立场上说,相对于将所有这些数据放入其中所需的工作,对于此特定操作,您可能无法使用关系数据库或任何其他数据库“系统”获得更好的性能一个数据库。

尽管我建议将数据加载到某种数据库(即成熟的编码数据管理系统)中,但您的文件很小。从您的问题来看,听起来您可以在恒定时间内识别出所需的文件,然后只需要读取和过滤(也许使用正则表达式?)最多 10MB 的数据,那么为什么需要关系数据库呢?

只需识别文件并通过 grep 管道它就完成了,对吗?这很有效。

具有适当索引(日期、名称)的关系数据库只会使第二步更有效率,即便如此,数据集也相当小——每个 10MB 文件中有几千行?

我知道通过将所有内容都保存在文本文件中,这听起来是一种非常粗略的解决问题的方法,但请保持简单。您必须管理数据的解析、验证和加载到数据库中,然后以数据库形式管理数据的额外存储等。

您没有提供任何信息,说明您需要执行此搜索的频率、您如何处理作为结果获得的数据或任何其他性能和操作要求。

如果您需要每秒多次执行此特定操作,或者想要灵活地以更具创造性的方式处理数据,或者对当前位于单独文件中的数据或类似的任何数量的数据执行任何类型的分析,那么关系数据库立即成为数据管理的最佳选择。

于 2012-11-28T20:25:44.283 回答
2

其他人已经提供了一些好的观点,让我稍微谈谈物理数据库结构......

如果可以的话,选择一个支持集群1的 DBMS 并创建一个 PK 为{Date, Name, No}2的集群(也称为索引组织)表。然后,您的 SELECT 可以满足于简单的索引范围扫描并且根本没有堆访问(表堆甚至不存在),因此您不必担心错误的集群因子。实际性能应该非常出色,并且可以很好地扩展到比您目前拥有的更多数据。

如果您的 DBMS 支持前沿索引压缩,请将其打开以消除此复合主/集群索引的 B-Tree 结构中重复值的存储(和缓存)成本。


1例如 Oracle、MS SQL Server、MySQL/InnoDB...

2 whereNo区分多行上的相同Date与相同Name。或者,只需Date更细化(例如精确到一秒),将查询修改为:SELECT * FROM myDB WHERE Name='Mickey Mouse' AND Date >= '2005-07-03' AND Date < '2005-07-04'),并将 PK 字段的顺序反转为{Name, Date},以满足修改后的查询。

于 2012-11-28T21:15:39.510 回答
1

我肯定会使用数据库,但是为问题选择正确的数据库需要更多信息,尤其是关于数据格式的信息。以下是我的建议,其中包含一些关于何时选择其中一个的详细信息:

关系:

如果您的所有数据都符合相同的模式(具有所有相同的字段),那么关系将是有意义的。从您的问题中,您提到您只需要 2 个索引,date并且name.

假设每个条目都有很多其他数据,那么 SQL 数据库会很有意义(使用类似于查询的东西)。

好处:

  • 你似乎已经知道它是如何工作的
  • 非常类似于 CSV 的做事风格
  • 您可以使用 SELECT/JOIN(如果您以后需要)

缺点:

  • 未使用字段的空间浪费
  • 不能很好地扩展(如果您需要更多空间)
  • 可能是矫枉过正,因为问题不是令人尴尬的关系

NoSQL:

如果您的数据不适合相同的模式(许多不同的键只有几个共享键),那么文档存储会更有意义。由于您的数据是一种关系数据,因此 MongoDB 会很有意义。

我会为您的数据库使用以下 JSON 指南:

{
    "name": "MickyMouse",
    "date": ...,
    other fields...
}

我会设置namedate成为索引,就像在 SQL 示例中一样。MongoDB 速度很快,并且不会占用额外的键空间。

这种方法的好处:

  • 扩展性非常好(您可以添加节点和分片)
  • 使用起来真的很简单

缺点:

  • 可能无法提供您需要的功能

结论:

两者都是很好的方法,但这实际上取决于数据的具体情况。一般来说,数据库非常擅长查询,而文件系统则不然,尤其是当数据变大时。

我个人会走 NoSQL 路线,但我真的需要更多关于数据集和使用模式的信息。如果数据需要扩展,那么这可能是最好的选择。

我不是真正的专家,但我只是不太喜欢使用 SQL。如果数据是令人尴尬的关系数据,那么 SQL 就很有意义,但您所做的一切似乎都适合一两个表。

于 2012-11-28T19:35:32.673 回答