【发布时间】:2015-07-08 07:30:34
【问题描述】:
我目前正在开发一个 PHP 应用程序(预发布)。
背景
我们的 MySQL 数据库中有一张表,预计该表会变得非常大 - 单个用户拥有该表中的 250,000 行并不罕见。表格中的每一行都有一个金额和一个日期等。
此外,在大多数页面上,此特定表的读取(和写入)非常频繁。鉴于每一行都有一个日期,我使用GROUP BY date 来最小化 MySQL 给出的结果集的大小 - 现在可以将同一年包含的行视为一个总数。
但是,一个典型的页面仍然会有 1000-3000 个结果之间的结果集。还有一些地方执行了许多SUM(),总共有数十(如果不是数百)数千行。
试用 MySQL
在通常的页面上,MySQL 通常需要大约 600-900 毫秒。使用LIMIT 和偏移量对性能没有帮助,而且数据已经被高度规范化,因此进一步规范化似乎没有帮助。
更糟糕的是,应用程序的某些部分需要从数据库中检索 10,000-15,000 行。然后将结果用于 PHP 的计算并进行相应的格式化。鉴于此,MySQL 的性能无法接受。
尝试 MongoDB
我已将表格转换为 MongoDB,它的速度更快 - 检索 2,000 个文档通常需要大约 250 毫秒。但是,聚合管道中的 $group 命令(需要根据字段所在的年份聚合字段)会减慢速度。不幸的是,在删除/更新/插入文档时保持总计和更新也是不可能的,因为虽然我们可以对应用程序的某些部分使用年度总计,但在其他部分,计算要求每个金额都落在具体日期。
我也考虑过 Redis,尽管我认为数据的复杂性超出了 Redis 的设计目标。
最后一根稻草
除此之外,速度也很重要。所以性能在优先级方面是最高的。
问题:
- 在知道大多数查询会检索到非常大的结果集的情况下,存储频繁读取/写入和快速增长的数据的最佳方式是什么?
- 是否有其他解决方案?我完全愿意接受建议。
我现在有点卡住了,我无法在可接受的时间内检索到如此大的结果集。似乎大多数数据存储都非常适合小型检索 - 即使是大量数据 - 但我无法从更大的表/集合中检索大量数据。
【问题讨论】:
-
您是否考虑过尝试一下 Elastica (elastic.co)?当谈到聚合/统计时,它真的很棒。通常,结合 MongoDB 编写 Elastica 索引并在后台保持最新是一个好主意。
-
当您查看核心时,没有数据库,也没有一个软件项目可以做与 MySQL 不同的事情。实际上,每次 MySQL 变慢都是因为没有配置。如果您想要性能,您需要硬件资源 - 足够的 RAM、良好的 CPU 和快速的 SSD。如果您没有这些,那么在软件方面您几乎无法做任何事情来使某些东西在过时的计算机上快速运行。长话短说 - 你的 MySQL 配置是什么?您希望所有内容都适合内存,以便快速进行所有聚合。
-
@iamtankist 我没有考虑过 Elastica。人们似乎在处理this issue 的一些问题。我想知道现在情况是否仍然如此?你自己用过吗?注:我的 MySQL 服务器位于本地机器上的一个 vagrant box 上,它可以很好地处理其他情况。我并不觉得硬件一定是这里的瓶颈,但是,我可能错了。
-
硬件永远是瓶颈。这就是 MySQL 附带默认配置的原因,因此它可以在非常非常旧且速度较慢的设备上运行。你的 MySQL 配置是什么?磁盘上的数据大小是多少?磁盘是机械的还是 SSD 的?你用的是什么存储引擎?您是否为 MySQL 所做的聚合操作分配了足够的 RAM?看到所有这些问题了吗?当 DB 很慢时,几乎总是因为它利用磁盘来查找数据或转储临时数据 - 而您的磁盘很慢。
-
@N.B.我明白你在说什么。作为预生产,数据库很小 - 我尝试保持所有表上的总行数
标签: php mysql performance mongodb scalability