【问题标题】:Is it faster to access data from files or a database server? [closed]从文件或数据库服务器访问数据是否更快? [关闭]
【发布时间】:2011-01-10 00:18:28
【问题描述】:

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

在处理文件和文件夹时,有哪些技巧可以提高性能?

【问题讨论】:

    标签: sql performance cgi flat-file


    【解决方案1】:

    我将添加到视情况而定的人群中。

    这类问题没有通用答案,但在很大程度上取决于手头的情况。我什至最近将一些数据从 SQL 数据库移到了平面文件系统,因为数据库的开销,加上一些数据库连接可靠性问题,使得使用平面文件成为更好的选择。

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

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

    2. 在一个程序执行期间我将多久访问一次数据?我会去一次以获取所有以塞林格为作者的书籍,还是会去几次以获取多个不同的作者?我会根据几个不同的标准去不止一次吗?

    3. 我将如何添加数据?我可以在末尾追加一行,这对于我的检索来说是完美的,还是需要使用它?

    4. 6 个月后代码看起来有多合乎逻辑? 我强调这一点是因为我认为这在设计事物时经常被遗忘(不仅仅是代码,这匹爱好马实际上来自我的时代作为一名海军机械师诅咒机械工程师)。在六个月内,当我必须维护您的代码(或者您在完成另一个项目之后)时,哪种存储和检索数据的方式会更有意义。如果从平面文件转换到数据库会导致 1% 的效率提升,但会增加一周的时间来弄清楚何时必须更新代码,那么你是否真的得到了改进。

    【讨论】:

    • 您能否根据您的问题添加您将使用的工具?模式似乎是:如果问题的第一部分是肯定的,那么使用文件,如果是第二部分,则使用数据库,但我不确定。
    【解决方案2】:

    一般来说,数据库比文件慢。

    如果您需要为文件编制索引,如果您正确执行,自定义索引结构上的硬编码访问路径总是有可能更快。

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

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

    所以:

    1. 您是否需要处理多个用户和并发更新? (嗯;你确实说过它是静态的。)
    2. 您是否需要灵活性以便从各种角度轻松查询数据?
    3. 您是否有多个用户,并且可以从利用现有安全模型中获益?

    基本上,问题在于哪个更容易开发。两者之间的性能差异不值得浪费开发时间。

    【讨论】:

    • 我要补充一点,性能优势只有在您知道自己在做什么的情况下才会存在。创建一个好的和快速的索引方案并不容易。数据库已经有几年的时间来微调他们的算法,即使它们是数据通用的。我认识的大多数试图用平面文件击败数据库的人都失败了。但是有些人在您需要它的罕见情况下取得了成功。
    【解决方案3】:

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

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

    2. 优化器。

    但是,对于某些专门的应用程序,与文件+文件夹数据存储相比,这两个好处都没有体现出来 - 因此答案是响亮的“取决于”。

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

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

    【讨论】:

    • 我不得不不同意你写的很多内容:1)数据库服务器上的缓存必须是通用的。如果您编写自己的特定应用程序知识 - 您应该能够轻松掌握它。 2) 优化器——同样,优化器必须是通用的;借助特定的应用知识,您可以编写更有效的访问路径,还可以利用典型 RDBMS 索引选项中不可用的结构。 3)大目录只有在你必须“搜索”文件时才会变慢;如果您有文件的完整路径,则无需“读取大目录的内容”。
    • @Sinan - 好的,给我上色,我需要一杯咖啡。就数据库与文件而言,您提到的“CGI 特定”问题是什么?
    • @Craig - 我不知道他的使用模式是什么。甚至他的数据是什么。所以你的观点可能有效也可能无效——这取决于。但是您的自定义文件结构是否知道将最常用的数据放在磁盘的较快区域?您是编写优质缓存的专家吗?这就是为什么我说“这取决于” - 在不知道他的应用程序的细节的情况下,我不准备以一种或另一种方式判断为他的需要编写一个基于自定义文件的结构是多么容易,这将击败 DB
    • @DVK:你是否知道他的使用模式并不重要。关键是知道(或应该),并且他的应用程序特定知识使得编写更好的缓存成为可能。当您拥有“主场优势”时,您不必“非常聪明”即可编写出色的缓存。问题与一般性能差异有关:实施不佳的数据库将与实施不佳的基于文件的解决方案一样糟糕。但是一个实施良好的基于​​文件的解决方案将胜过实施良好的数据库解决方案(但开发时间成本要高得多)。
    • @Sinan - 我被 mod_perl 宠坏了 - 它消除了启动速度的库负载和编译损失。
    【解决方案4】:

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

    我的一点经验是使用 PostgreSQL。我有一个包含 300 万行的表,而我只更新了 8,000 条记录。耗时 8 秒。

    至于“过早的优化是万恶之源”这句话,我持保留态度。如果您使用数据库编写应用程序,然后发现它很慢,则可能需要大量时间才能切换到基于文件系统的方法或其他方法(例如 SQLite)。我会说你最好的选择是创建一个非常简单的工作负载原型,并使用这两种方法对其进行测试。我认为在这种情况下知道哪个更快是很重要的。

    【讨论】:

      【解决方案5】:

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

      如果您真的需要找出哪个对您的目的性能更高,您可能需要生成一些示例数据以存储在每种格式中,然后运行一些基准测试。 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 以获取更完整的文档。

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          这取决于数据的配置文件以及您将使用什么逻辑来访问它。如果您只需要保存和获取命名节点,那么基于文件系统的数据库可能会更快、更高效。 (为此,您还可以查看 Berkeley DB。)如果您需要进行基于索引的搜索,特别是如果您需要根据键连接不同的数据集,那么 SQL 数据库是您的最佳选择。

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

          【讨论】:

            【解决方案8】:

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

            特别是对于 CGI 脚本,在每次页面查看时连接到数据库服务器都会导致性能下降。但是,如果您创建一个简单的基于文件的方法,则很容易产生更糟糕的性能问题;-)

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

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

            【讨论】:

              【解决方案9】:

              要快速访问文件,取决于您正在做什么,mmap 非常方便。我刚刚在Effective Perl 博客中以Memory-map files instead of slurping them 的身份写过这个。

              但是,我希望数据库服务器会快得多。当我们不知道您在做什么、您需要访问什么样的数据等等时,很难说什么对您来说更快。

              【讨论】:

                【解决方案10】:

                database certainly can be faster,

                引用 SQLite 测试,

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

                此外,与将 Blob 存储在单个文件中相比,一个保存 10 KB Blob 的 SQLite 数据库使用的磁盘空间减少了约 20%。

                出现性能差异(我们相信)是因为在 SQLite 数据库中工作时,open() 和 close() 系统调用仅调用一次,而在使用时为每个 blob 调用一次 open() 和 close()存储在单个文件中的 blob。看来调用 open() 和 close() 的开销大于使用数据库的开销。大小减小的原因是单个文件被填充到文件系统块大小的下一个倍数,而 blob 被更紧密地打包到 SQLite 数据库中。

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

                【讨论】:

                  【解决方案11】:

                  就像其他人所说的 DB 是一种工具,它会产生一些开销,但如果您的数据是静态的并且它是只读数据,从文件中读取目录会更快: 以下是我做过的一些测试: 我的文件名称为 .csv 在数据库中,我将列索引为“日期”,以便在数据库中找到相同的记录。每天有 30K-50K 记录/行和 100 列不同类型的数据(90% 浮动)。

                  数据库信息: PostgreSQL 11.5,16GB 内存

                    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 倍

                  【讨论】:

                    【解决方案12】:

                    我会给你和其他人一样的答案, 视情况而定

                    在单个服务器返回数据(只读)的简单场景中,是的文件系统将非常好并且易​​于管理。

                    但是,当您拥有多个服务器时,您将不得不管理分布式文件系统,例如 glusterfsceph 等。

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

                    希望对您有所帮助。

                    【讨论】:

                    • 您的意思是“取决于”吗?
                    【解决方案13】:

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

                    其实这是我从那以后做出的最不负责任但幸运的是最合适的决定。

                    为了处理这个文件系统,我还设置了一个 php 函数集以简化内容。我考虑使这些功能的事情是:

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

                    就是这样。

                    但在使用它时,我不得不考虑优化。例如,当谈到某人的最后一次见面时..

                    当某人 X 用户想要查看其他 Ylastseen 时,我创建了一个名为 dataRequestingCluster 的文件夹,并在 X 下,其中包含 X 想要看到最后一次看到的所有内容(可能是 @ 987654327@ 的好友列表,如果 X 正在查看他的好友页面)并将该集群添加到 Y 的最后一次看到的表中(其中包含所有“Y 的最后一次看到的请求者单独的集群文件”并且每次更新 Y与服务器交互)

                    然后添加了一个机制,在 3 分钟内不使用时删除 dataRequestClusters(当 X 离开他的朋友页面时,无需为他更新最后一次看到)

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

                    最重要的是,这种方法比使用 MySql 的数据库系统要快得多……但是你必须动用大脑,多花 30% 的时间,但由此带来的快乐和完整性太棒了

                    这只是“最后一次见到”的一个案例

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

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

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

                    【讨论】:

                    • 您能分享一些您使用的代码、语言或工具吗?
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-06-24
                    • 2016-07-08
                    • 2014-06-08
                    • 2019-07-18
                    • 1970-01-01
                    相关资源
                    最近更新 更多