从文件或数据库服务器访问数据是否更快?

时间:2010-01-27 15:04:35

标签: sql performance cgi flat-file

如果我有一个由文件夹和文件组成的静态数据库,访问和操作会比SQL服务器类型数据库更快,考虑到这将在CGI脚本中使用吗?

使用文件和文件夹时,有哪些提高性能的技巧?

14 个答案:

答案 0 :(得分:51)

我会加入它取决于人群。

这是一个没有通用答案的问题,但严重依赖于手头的情况。我最近甚至将一些数据从SQL数据库移动到平面文件系统,因为数据库的开销加上一些数据库连接可靠性问题,使用平面文件是更好的选择。

在做出选择时我会问自己的一些问题包括:

  1. 我如何使用数据?例如,我只是按照输入的顺序从开头到结尾读取?或者我会搜索符合多个条件的行吗?

  2. 在一次程序执行期间,我多久会访问一次数据?我会去一次用Salinger作为作者获得所有书籍,还是会多次去找几位不同的作者?对于几个不同的标准,我会不止一次?

  3. 我将如何添加数据?我可以直接添加一行,这对我的检索是否完美,还是需要使用?

  4. 代码在六个月内看起来有多合理?我强调这一点,因为我认为这在设计事物时经常被遗忘(不仅仅是代码,这个爱好马实际上来自我的日子)作为海军机械师诅咒机械工程师)。在六个月内,当我必须维护你的代码时(或者你在另一个项目之后你做了),哪种存储和检索数据的方式会更有意义。如果从平面文件转换到数据库导致效率提高1%,但是当你必须更新代码时,需要花费一周的时间来解决问题,你真的改进了。

答案 1 :(得分:17)

取决于您的信息是什么以及您的访问模式和规模。关系数据库的两大好处是:

  1. 缓存。除非你非常聪明,否则你不能写出与数据库服务器一样好的缓存

  2. 优化。

  3. 然而,对于某些专门的应用程序,与文件+文件夹数据存储相比,这两种好处都没有表现出来 - 因此答案是响亮的“依赖”。

    至于文件/文件夹,技巧是:

    • 缓存常用文件的内容
    • 拥有小目录(由于读取大目录内容所需的时间,深度嵌套的小目录中的文件比访问更平坦的结构更快。)
    • 还有其他更高级的优化(跨磁盘切片,放置在磁盘或不同分区的不同位置等等) - 但如果您需要THAT级别,那么您最好先使用数据库的地方。

答案 2 :(得分:14)

作为一般规则,数据库比文件慢。

如果您需要索引文件,那么如果您正确执行此操作,自定义索引结构上的硬编码访问路径将始终更快。

但是,在基于文件的解决方案中选择数据库时,'性能'不是目标。

您应该问问自己,您的系统是否需要数据库提供的任何好处。如果是这样,那么小的性能开销是完全可以接受的。

所以:

  1. 您需要处理多个用户和并发更新吗? (好吧;你确实说它是静态的。)
  2. 您是否需要灵活性才能从各个角度轻松查询数据?
  3. 您是否拥有多个用户,并且可以从使用现有安全模型中获益?
  4. 基本上,问题是更容易开发的问题。两者之间的性能差异不值得浪费时间。

答案 3 :(得分:8)

从我的一点经验来看,与本地文件系统相比,基于服务器的数据库(甚至是在本地机器上提供的数据库)往往具有非常慢的吞吐量。然而,这取决于某些事情,其中​​之一是渐近的复杂性。比较扫描大型文件列表与使用数据库和索引来查找项目,数据库获胜。

我的一点经验是使用PostgreSQL。我有一张300万行的表,我只更新了8,000条记录。花了8秒钟。

至于引用“过早的优化是所有邪恶的根源。”,我会带着一丝盐。如果使用数据库编写应用程序,然后发现它很慢,则可能需要花费大量时间才能切换到基于文件系统的方法或其他方法(例如SQLite)。我想说你最好的办法就是创建一个非常简单的工作负载原型,并用两种方法进行测试。我认为在这种情况下知道哪个更快是很重要的。

答案 4 :(得分:4)

正如其他人所指出的那样:这取决于!

如果确实需要找出哪个更适合您的目的,您可能希望生成一些样本数据以每种格式存储,然后运行一些基准测试。 Benchmark.pm模块附带了Perl,并且可以很简单地与这样的东西进行并排比较:

use Benchmark qw(:all) ;

my $count = 1000;  # Some large-ish number of trials is recommended.

cmpthese($count, {
    'File System' => sub { ...your filesystem code... },
    'Database'    => sub { ...your database code... }
});

您可以输入perldoc Benchmark以获取更完整的文档。

答案 5 :(得分:3)

如果站点结构合适,在图像方面使用文件而不是db非常有用。创建表示匹配数据的文件夹并将图像放入其中。例如,您有一个文章站点,您将文章存储在db中。您不必将映像路径放在db上,使用主键(如1,2,3 ..)命名文件夹,并将图像放入其中。电子书,音乐文件,视频,这种方法可用于所有媒体文件。如果您不搜索某些内容,则相同的逻辑与xml文件一起使用。

答案 6 :(得分:1)

这取决于数据的配置文件以及您将用于访问它的逻辑。如果您只需要保存并获取命名节点,那么基于文件系统的数据库可能更快,更高效。 (你也可以看看Berkeley DB。)如果你需要进行基于索引的搜索,特别是如果你需要基于密钥加入不同的数据集,那么SQL数据库是你最好的选择。 / p>

我会选择最适合您应用的解决方案。

答案 7 :(得分:1)

正如其他人所说,取决于:数据的大小和性质以及您计划在其上运行的操作。

特别是对于 CGI脚本,您将在每个页面视图上连接到数据库服务器时遇到性能损失。但是,如果您创建一个简单的基于文件的方法,您可能很容易造成更糟糕的性能问题; - )

除了Berkeley DB File解决方案,您还可以考虑使用 SQLite 。这将为存储在本地文件中的数据库创建一个SQL接口。您可以使用DBI和SQL访问它,但没有服务器,配置或网络协议。如果将来需要数据库服务器,这可以允许更容易的迁移(例如:如果您决定拥有多个前端服务器,但需要共享状态)。

在不知道任何细节的情况下,我建议使用SQLite / DBI解决方案,然后查看性能。这将为灵活性提供一个相当简单的启动和良好的性能。

答案 8 :(得分:1)

要快速访问文件,根据您的操作,mmap非常方便。我刚刚在Effective Perl博客中写了Memory-map files instead of slurping them

但是,我希望数据库服务器会快得多。当我们不知道你在做什么,你需要访问什么类型的数据等等时,很难说你的速度会更快。

答案 9 :(得分:1)

我为我的办公室管理站点(遍布美国和巴西的100万名工人)选择了文件/文件夹系统,这是我的第一个项目(作为工作)。

实际上,这是我自那时以来做出的最不负责任但最合适的决定。

为了处理这个文件系统,我还制作了一个php函数集来简化内容。我认为要实现这些功能的事情是:

  • 创建表文件(如csv)
  • 创建包含这些文件的文件夹,
  • 让所选文件中的每一行重复一个功能,
  • 反复更改/删除选定文件中的选定列/行数据
  • 并将二进制文件另存为单独的文件

仅此而已。

但是在使用它时,我不得不考虑进行很多优化。例如,当最后一次见到某人时。

某人X的用户想要查看其他lastseen的{​​{1}}时,我在Y下创建了一个名为dataRequestingCluster的文件夹,其中包含{ {1}}希望查看最后一次看到的(如果X正在查看他的朋友页面,则可能是X的朋友列表),并将该群集添加到X的最后一次看到的表中(其中所有“ X的最后一次出现的请求者都将clusterFiles分开”,并且每次Y与服务器进行交互时都会更新)

然后添加了一种机制,可在3分钟不使用时删除dataRequestClusters(当X离开他的朋友页面时,无需更新上次见到他的信息)

我必须遵循这种方法,因为更新ALL_USERS文件中最后一次看到的时机是一个完全的笑话。

最重要的是,这种方法比使用带有MySql的数据库系统要快得多……但是您必须多动脑筋,而且要多花30%的时间,但是这样做带来的幸福感和完整性令人敬畏

这只是一个“最后一次见过”的情况

很多次我使用不同的算法来解决每个问题,而且它总是比sql / db系统有效。

结论:文件系统使事情变得复杂,但这是以令人震惊的方式提高质量的唯一方法...如果您不善于思考或时间较少,或者您不感兴趣您可能应该使用SQL / DB系统。

六个月后,我的服务器数据存储达到20GB(没有媒体文件。仅用户信息),但是任何单个文件都没有超过200kb。。它以最少的处理时间取得了惊人的成功。

答案 10 :(得分:1)

database certainly can be faster

引用SQLite测试,

SQLite读写小块(例如缩略图)的速度比使用fread()或fwrite()从磁盘上的单个文件读取或写入到磁盘上的单个文件快35%¹。

此外,单个SQLite数据库中包含10 KB的blob,其磁盘空间比将blob存储在单个文件中的磁盘空间少约20%。

之所以会出现性能差异,是因为在SQLite数据库中工作时,open()和close()系统调用仅被调用一次,而open()和close()对于使用时每个blob都被调用一次。存储在单个文件中的Blob。看来,调用open()和close()的开销大于使用数据库的开销。大小减小是由于以下事实:将单个文件填充到文件系统块大小的下一个倍数,而将斑点更紧密地打包到SQLite数据库中。

本文中的测量是在2017年6月5日那一周使用3.19.2至3.20.0之间的SQLite版本进行的。您可能希望SQLite的将来版本会表现得更好。

答案 11 :(得分:0)

我打算给你其他人给你的答案, 取决于

在一个简单的场景中,只有一台服务器返回数据(只读),Yes文件系统将非常棒且易于管理。

但是,如果您有多台服务器,则必须管理分布式文件系统,如glusterfsceph等。

数据库是为您管理所有数据库,分布式文件系统,压缩,读/写,锁等的工具。

希望这很有帮助。

答案 12 :(得分:0)

就像其他人所说的,DB是一个工具,它会产生一些开销,但是如果您的数据是静态的并且它是只读数据,则从文件中读取目录会更快: 这是我已经完成的一些测试: 我有名为.csv的文件 在数据库中,我已将列索引为“日期”,以便在数据库中找到相同的记录。每天有3万至5万条记录/行以及100列不同类型的数据(浮点数为90%)。

数据库信息:   PostgreSQL 11.5,16GB RAM

  Table:
    335,162,867 records
    Table size: 110GB
    Index size: 7GB
    Total size: 117GB
  Files:
    Number of files: 8033
    Total Files size: 158GB
    Number of records/lines per file/date: 30K - 50K
  

不断从文件读取随机日期(1986-2019年)的数据   比在PostgreSQL中读取相同日期的数据快4-5倍

答案 13 :(得分:-2)

有趣的见解。

Tx Guys and gals ..

似乎确实确实取决于解决方案的整体设计和使用情况(因此,如果我不能很好地理解未来的要求,我并不总是喜欢敏捷)

我想从大型机方法中添加其他注意事项。

通常,我们处理大数据和小窗口,因此性能非常关键,但是可靠性,可维护性,可持续性,可扩展性也很关键(Ja所有功能:-) 还有一致性和完整性..好的,我想您已经明白了。

我们在这里了解到的是,通常当您以批处理方式处理时(批量数据到达单个时间点,即像月底到期的所有借项一样),我们将使用文件。通常是索引编制还是固定索引,具体取决于您是否需要键控访问或分别读取每个最后一条记录。 文件通常是预先分配和定义的,并仔细考虑了块大小以对齐页面。请记住,平面读取实际上将检索块,每个读取命令可能依次包含多个记录,因此,如果正确对齐,则在以不太理想的方式进行检索时,不会导致文件系统管理器必须工作(未对齐)记录大小)或动态重新分配其分配和索引等。(与GC非常相似);如果无法进行脏/未提交的读取等操作,则将记录锁定在页面或块级别。或者在中间留出空间来放置某些内容在运行带有随机插入等的索引文件时。 因此,有时即使从一个输入到另一个输入或在两个输入之间有很大比例的键插入,您也可以使用平面文件,并在运行时使用最可能的文件作为驱动程序文件来执行低键逻辑匹配之类的操作。 ..我们有时甚至发现将DB转储到平面文件中,然后再处理并重新加载(例如,如果您要击中所有记录的话)会更有效,或者有时甚至直接读取基础DB文件。弹性的一个不错的选择是,有时如果数据库连接或其他原因导致它不可用,并且您需要继续读取,然后检查返回码并在返回码出错时直接读取dB文件系统)。 通常,根据驱动程序文件逻辑(驱动主逻辑。即,对该主文件上的每个记录执行... XYZ ..),这些规则通常是为平面文件处理定义的,这些文件通常预先排序为第一步,使用基于高速程序集的排序实用程序来适应记录处理中预期的逻辑中断(即您要对每个客户端进行处理,然后对客户端或每个分支进行预排序,然后对分支进行预排序等)。

无论如何,当涉及到高速实时需求(与批处理批量相反)时,我们通常会使用DB。通常,这与UI,事务(消息传递)/事件驱动/交互式类型的用例有关,因此更适合直接/键控访问,并且几乎不需要批处理所需的响应。 您还可以自动读取并锁定记录级别,以确保完整性(如果您不关心完整性,并且负担得起未提交的/脏的,也可以更快地读取)...

如果考虑到这一点,则OS是基于文件系统的,因此DB最终必须基于文件系统。.然而,该DB已针对典型的基于事件/实时,并发和高完整性要求的用例进行了优化。开发人员有时必须付出很多努力才能在实时/事件驱动的场景/用例中获得所有这些功能。在复杂的流程上考虑死锁,回滚,同步点,并发等。并保持高度响应。

写这篇文章让我意识到,在决定使用什么以及何时以及为什么时还有更多的考虑要考虑。有时,即使在不同点的相同数据也最适合于不同的选择。您可能会使用数据库或针对此数据进行了优化的其他更简单的直接键控访问方法从前端获取数据,但您可能希望将其放在文件系统上 例如,如果您必须在每月的特定时间对该数据进行每月检查,并处理平面文件。 这似乎确实意味着所有这些都取决于设计。举例来说,如果您由于响应要求而在执行事务/事件时不能做某些事情,而不得不推迟到以后再保持完整性等。更简单的过程,而不必推迟等。 它也将非常依赖于域。即您知道Google返回搜索结果时是否错过了随机点击吗?但是我敢打赌,您会知道您的银行何时不显示交易(尤其是贷记给您的..lol)...