【问题标题】:MySQL taking too much time for query, Is NoSQL the solution or something like elasticsearch would work?MySQL 花费太多时间进行查询,NoSQL 是解决方案还是弹性搜索之类的解决方案?
【发布时间】:2014-05-23 03:34:45
【问题描述】:

我有一个包含数百万行的 mysql 表。每行都有一个 id、data、date。

  1. id -> 数量
  2. 数据 -> 长文本
  3. 日期 -> 日期时间

“数据”列包含 json 编码数据,数据列中的每一行大约为 . 45kb,如果我需要查询 100 行,它返回 45kb x 100 = 4500kb 的数据。要求是将来获取 10,000 或 100,000 行。

json 编码的数据,然后在服务器端(PHP)进一步解码,然后应用程序使用数据。

应用程序服务器和数据库服务器都是分开的。目前查询 100 行(查询是在日期完成的),同时查询并将数据传输到应用程序服务器进行渲染,花费了太多时间。

请建议优化解决方案以实现极快的访问(100,000 行)。

NoSQL (mongodb) 是一个好的解决方案,还是 elasticsearch,或者 MySQL 有针对这种场景的优化技术?

【问题讨论】:

  • 你试过 Postgres 吗?它具有原生 JSON 列,这可能意味着您不必传送整个 JSON 数据结构,而只需传送相关部分。
  • 在mysql中使用MYISSAM作为存储引擎
  • 您在表上运行的实际查询是什么?
  • 还没试过postgres。要求指出,有时需要整个 JSON 数据,有时需要相关部分。最终目标是获得整个数据列 45 kb 行(n 行)但 v.fast。
  • 查询是 'SELECT * from table WHERE DATE BETWEEN '2014-3-3' AND '2014-3-4' 每 5 分钟一次,通过 CRON 输入一个新行。

标签: mysql performance mongodb optimization elasticsearch


【解决方案1】:

免责声明:我为 MongoDB 工作,开发 PHP 驱动程序。

在 MongoDB 中,“数据”字段将成为另一个普通的子文档。没什么特别的。它只是一组信息。就像我们喜欢的那样:) 你可以用任何你想要的方式查询它。您可以获取所需的任何部分。你可以随意索引它。

这正是 MongoDB 等面向文档的数据库的出色表现——因为它们在设计之初就考虑到了此类数据

你没有说这个 JSON 编码的数据到底是什么,或者看起来像什么,所以我无法说出确切的细节......我建议你自己尝试一下。使用各种系统构建概念验证,然后选择最高效且最适合您的用例的系统。

有关其工作原理的示例,请参阅 http://us2.php.net/manual/en/mongo.tutorial.insert.php(以及本教程的其余部分)。

现在,我们实际上并不以 JSON 格式存储数据(我们使用 BSON,二进制 JSON),因此您不必将数据编码为 JSON。只需使用普通的 PHP 数组和对象 - 反正这样会更快。

【讨论】:

  • 我试过了。将整个数组(PHP)作为文档存储到 mongo 中。通过这种方式,我有 1000 个文档,并且在 MySQL 中有类似的 1000 行(如上所述)。与 MySQL 相比,MongoDB 将数组(数据列,不是 json 编码)存储为文档花费了太多时间。另一方面,如果我将 JSON 编码的字符串存储在文档中的 Mongo 中,它会快一点,但它是 json 字符串,所以如果需要数据子部分,则无法处理。
  • 您能给我看一个完整文档的示例,以及该集合的索引吗?对 1000 个文档进行排序应该是即时的。
  • 在这里显示整个文档会太大。对 mongo 文档应用“索引”后会产生什么影响?
  • 为了获得最佳性能,在任何数据库中,您都必须“选择正确”的索引策略。您查询和排序的内容需要编制索引。如果它们没有被索引,那么数据库需要做的工作是非凡的,您也可以聘请训练有素的猴子手动查看数据并在找到时给您打电话。在您正在查询/排序的字段上使用索引但是这项工作变得微不足道并且“超级快”
【解决方案2】:

绝对没有理由不能使用 MySQL。 在如此大的表中快速访问数据最重要的是为您的查询建立良好的索引。

如果您想获取特定日期的数据,请确保您有这样的索引:

ALTER TABLE `yourtable` ADD INDEX `yourindex` ( `date` , `data` )

这就是 MySQL 优化器处理查询的方式: 1.过滤(WHERE子句) 2. 分组(GROUP BY 子句) 3. 排序(ORDER BY 子句) 4. 选择数据(SELECT * 子句)

您应该完全按此顺序创建索引,以完全满足您的查询,仅使用索引而不进行表扫描。

如果需要的数据已经是前三个索引部分的一部分,则不必向索引添加额外的列。

对于较小的表,如果您不需要高性能,则仅在过滤列上建立索引可能就足够了。

【讨论】:

  • 他不应该索引数据,因为它的大小是 45kb,这意味着它是一个文本或 blob,如果可能的话,索引会很大。也就是说,必须在 where 子句日期字段上设置索引。这个用例可能不适合 MySQL,因为 BLOB 和 TEXT 类型字段有性能损失。不确定为什么要使用 MySQL 来存储非关系数据,Elastic 或 Mongo 几乎肯定更适合。
【解决方案3】:

我无法在 MySQL 中提出解决方案——对此没有太多经验,但我所知道的数百万行在 MySQL 中应该没有问题(在 SQL Server 中从来不是问题)。就 MongoDB 而言,除非您进入数十亿或具有更高前景的行的区域,否则不要考虑 MongoDB 或任何其他 NoSql 解决方案。

我现在正在开发一个以 MongoDB 作为后端的网站。我们在 MongoDB 中存在搜索缓慢的问题,并且我们正在查询的集合的大小只有 400K 文档。我们设想它在未来更像是 50M 文件,所以这是一个大问题。虽然搜索很复杂(它使用了多个字段,包括嵌套文档中的字段,但没有理由让它在 400K 文档中这么慢)。因此,我们考虑的解决方案之一实际上是为特定的集合/表和特定的搜索使用一些 SQL 数据库(甚至可能是 MySQL)。为了加快搜索速度,我们已经放弃了共享该集合,这增加了一些搜索速度,但没有那么多。

底线是:小心使用 MongoDB——它不是灵丹妙药!

【讨论】:

  • 如果您愿意,我很乐意与您一起调试性能问题。您能否发布示例文档的示例、您的搜索条件和集合中的索引?
  • 你尝试过 Elasticsearch 吗?
【解决方案4】:

有几种方法可以做到这一点

1) 使用 MYISSAM
2) 尝试规范化 json 数据
3) 使用索引
4)缓存,使用Memcache

我能想到的最后一个解决方案是使用单独的数据库服务器,它具有所有存储过程、获取所需数据的功能,并确保您只向该服务器发出一个请求。

就像你说的压缩和解压缩需要时间,那么这样做没有意义。尝试寻找其他可以优化的东西,例如 javascripts 、 HTML 加载时间,然后让 ajax 为您完成数据传输。解决问题,优化所有简单的东西。

【讨论】:

    【解决方案5】:

    一个老问题,但让我们来回答吧。如here 所述,如果记录大小超过 7kb,则其余数据将单独存储。按索引获取数百万条记录需要几毫秒,但读取和交付需要几秒钟。因此,似乎长时间执行主要取决于需要物理读取和传​​输的数据量(45kb*100.000 ~ 5Gb)。

    【讨论】:

      猜你喜欢
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多