6

我的应用程序用于查询,有 m:n mysql 表:

  father(id,name)
  child(id)
  join_f_c(fatherId,childId):middle table between father and child

有查询场景:

(a): select * from father f,child c,join_f_c jfc where f.name=xxx and join_f_c.fatherId=f.id and join_f_c.childId=c.id
(b): select * from father where f.id=xxx
(c): select * from father where f.name=xxx

父表有 100,000 行,子表有 1000,000+ 行,grandChild 表有 1000,000+ 行。

在这个应用程序中,所有查询都需要很高 的查询性能 - 不仅仅是针对特定行的第二次查询,所以我想在应用程序启动时将所有表数据加载到 memcached中,这些是问题:

1.每个(a)查询会询问memcached 3次:通过name获取父亲id,然后通过join_f_c通过fatherId获取childId,最后通过child从child获取child,这将导致大约0.5ms。memcached 是否适合此连接查询?如果我只是把查询结果放到 memcached 中,会浪费很多空间——很多子行会有很多副本,例如:father1-child1,father2-child1。

2.对于(b)和(c)查询,我需要将每个父表行两次放入memcached:一个键是id,另一个键是name,这会浪费很多缓存空间。有没有更好的方法呢?

任何帮助将不胜感激

4

2 回答 2

6

关于 Memcached

Memcached 是一个键/值对存储。您无法查询 Memcached 值的内容。您只能请求完整的价值。

显然,在 Memcached 中存储整个表(有 100.000 行)并请求 PHP 读取/使用表的整个值将是 PHP 的巨大内存和计算工作,这会显着减慢您的速度。

每个键只存储一个表记录对于 PHP 来说是可以管理的,并且会提高性能,但在 PHP 和 Memcached 之间的通信方面会非常浪费。

一般用法

Memecached 通常用于存储通常大于一个表记录的内容,例如,如果您正在创建基于类别/子类别的菜单,您可以将整个类别树存储在一个键中。您可能需要在每个页面上呈现该类别树或在每个页面上进行 ajax 处理,因此将其放在缓存中是可行的。

很多时候,Memcached 用于存储读取的输出,例如整个 HTML 页面,或使用某些数据 + 模板呈现的页面(块)的 HTML 片段,这意味着您可以节省重建该块的计算工作量。

需要考虑的事项

键命名约定将帮助您正确检索已放入 Memcached 的数据。

当数据库中的数据发生变化时,您可能也想在 Memcached 中更新它,或者只是从 Memcached 中删除它,以便下一个需要它的进程重新构建它,或者保持 memcached 版本不变(陈旧数据),因为您的应用程序可以接受显示较旧的数据(在某个“可接受”期间)。

命名约定对于从 Memcached 更新或删除陈旧数据非常重要,因为数据库中的一个微小更改可能会影响存储在 Memcached 值中的许多内容,能够找出这些内容对于准确的缓存清除很重要。

于 2013-11-04T15:03:29.900 回答
1

在我看来,您只是想将数据库复制到内存中,并且要花费更多的空间和精力。我只是确保您在数据库服务器上有足够的内存来在内存中保存一个工作集(如果不是全部的话)。然后只需进行一次连接即可在一个请求中获取您需要的所有信息。

数据库擅长它们的工作 - 使用它们,直到你遇到限制,然后通过重写查询来开始解决它们以避免连接和使用缓存。

于 2013-11-04T16:11:45.600 回答