我的项目有一个mysql数据库和一个由Clojure编写的后端。
数据库的某些表每天只更新一次,以查询最新的 我们将使用的信息。
可是:
数据库非常大,网络速度慢,所以每个查询都会 需要几秒钟。
我们需要在每次查询后进行复杂的计算。
我们需要进行多种sql查询,因此保存每个sql查询的结果是不现实的。
我们需要经常更改计算功能 调试的目的。
在sql查询速度慢的情况下,现在所有事情都太慢了。
幸运的是,我们的数据每天只会更新一次,而且数据库中的一些查询经常被使用。
所以我们想要缓存常用的sql查询和中间结果。
Clojure的memoize
功能对这类工作有用吗?我担心sql查询不纯,所以memoize
不应该缓存他们的结果。但是有一天我们的sql查询结果必须相同。
我可以在一天内memoize
结果并在第二天自动更新结果吗?
感谢您的帮助!
答案 0 :(得分:6)
你应该使用缓存,例如: G。 clojure.core.cache。
澄清注释:memoization有助于纯函数:如果你的函数在给定相同输入的情况下总是返回相同的输出,你可以在计算一次后存储它。
如果输出随时间变化,则需要进行失效。带有失效的记忆(以及一些其他问题,例如记忆事物的大小)被称为"缓存"。
如果使用memoization机制进行缓存,那么您实际执行的操作就是在其上实现缓存。使用缓存库的工作要少得多。
在这种情况下,您需要在午夜和#34;执行类似"失效的操作。有关如何执行此操作的说明,请参阅https://github.com/clojure/core.cache/wiki。
编辑:它可能看起来像这样(未经测试,带上你自己的today
):
(defcache MidnightCache [cache dates]
CacheProtocol
(lookup [this key]
(lookup this key nil))
(lookup [this key not-found]
(if (has? this key)
(get cache key)
not-found))
(has? [this key]
(let [d (get dates key)]
(and d
(= d (today)))))
(hit [this key]
this)
(miss [this key new-value]
(MidnightCache. (assoc (dissoc cache key)
key new-value)
(assoc (dissoc dates key)
key (today))))
(evict [this key]
(MidnightCache. (dissoc cache key)
(dissoc dates key)))
(seed [this base]
(MidnightCache. base
(zipmap (keys base)
(iterate identity (today))))))