0

我正在处理包含数百万条记录的表,并且经常必须运行查询以报告针对它的原因,这可能需要数小时,具体取决于连接级别和其他原因。我知道有很多方法可以优化查询,但我对另一种方法的可能性很感兴趣。

是否有可能通过 PHP(不是 MySQL 原生)获取 MySQL 查询的结果(比如“SELECT * FROM table”),将其作为数组存储在 Memcached 中,然后针对该缓存版本运行查询?会更快吗?粗略地说,这将如何工作?通过查询我的意思是,搜索一个可能看起来像这样的数组:

Array[0] {
   Array[0] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   },
   Array[1] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   }
   Array[2] {
      'field1' => 'value1',
      'field2' => 'value2',
      'field3' => 'value3'
   }
}

有没有办法比允许 MySQL 进行查询更有效地“查询”PHP 数组?真的,这一切听起来像是利用 NoSQL 解决方案的绝佳机会,但是,唉,我无法控制它。

[编辑]

我们正在处理分布在大约 50 个数据库中的数据,每个数据库可能包含 50 个表,每个表的行数从 50 万到 5000 万不等。这都是遗留问题并且优化不佳。只是想用我所拥有的东西工作。

所有数据库都在同一个从服务器上,是的,需要进行跨数据库的查询。这是一个混乱的情况,我只是希望看看我是否可以通过代码更好地处理它而不是让 MySQL 完成工作(据我所知,答案可能是否定的)

4

2 回答 2

1

这取决于您正在运行的查询类型,但最有可能的是,您会看到性能大幅下降(更不用说您必须首先将数百万行加载到内存缓存中,这可能需要相当多的时间)。您可以运行报告,然后将结果存储到内存缓存中,但这实际上取决于访问它们的频率以及其他几个考虑因素。

根据您正在运行的报告类型,通常不应该花费数小时来仅针对数百万行进行报告。您是否尝试过针对您的报告查询运行 EXPLAIN 以确定您是否没有在某处使用正确的索引,或者您是否可以为您正在运行的查询类型创建更有效的结构?

另一种可能性是您的数据库服务器超载,您可能会通过设置从属服务器并针对该服务器运行报告查询来获得更好的性能提升。

编辑:在获得有关您当前不幸情况的更多信息后,仍有几个可能的选择。在没有任何模式或 EXPLAIN 输出的情况下尝试帮助优化这种情况确实很难,但我认为如果您仔细分析所有查询并进行任何可能的优化(例如添加索引),您可能能够提高性能)。这会很乏味。

另一种可能性是分别针对每个不同的数据库运行报告,然后将结果合并到某个共同的地方。

于 2012-08-15T14:20:53.270 回答
-2

Memcached 是一个对象级缓存。它不提供 SQL 接口。因此,您的想法与 memcached 不兼容。但是,有几种可能性。

对于您遇到的每个查询,首先计算一个哈希码。哈希必须包括进入查询的所有参数。当您检索数据时,将结果转换为数据传输对象(XML/文本等)并将哈希和数据对象存储在内存缓存中。

现在,每次要运行查询时,首先创建它的哈希,查找它是否存在于缓存中,如果存在,则取它,否则,从数据库中获取并将其放入缓存中。

当您更新数据库时出现问题,缓存过时并且您需要刷新它。如果你的业务是这样的,你可以忽略最新的数据,你可以周期性地使缓存失效。也就是说,即使数据存在于缓存中,但它是在 1 小时前取回的,你会再次取回。这是一种策略。

您还可以创建一个后台进程来扫描缓存和数据库,并使用数据库中的触发器以伪实时方式刷新它。对数据库的每次更新都会创建一条消息,用于更新缓存。

一种更复杂的方法是,预处理所有数据库更新,并在进行更新之前使受影响的缓存条目无效。

缓存很容易。使其无效很难。您需要在缓存数据之前找出失效。

- 附录

有时您无法进行查询。标准的 jdbc 接口太慢了。您将碰壁,您无法进行足够的调用,因此此时,它不是数据库,而是数据库的路径。如果您想了解更多相关信息,请阅读 handlersocket 以及 Facebook 如何扩展他们的查询。

http://gigaom.com/cloud/facebook-shares-some-secrets-on-making-mysql-scale/

处理程序套接字:

http://yoshinorimatsunobu.blogspot.com/search/label/handlersocket

于 2012-08-15T14:28:16.790 回答