2016-10-27 5 views
1

내 프로젝트에는 Clojure가 작성한 백엔드와 MySQL 데이터베이스가있다.Clojure의`memoize` 함수는 느린 SQL 쿼리와 복잡한 계산을 캐싱하는데 유용합니까?

우리가 사용할 최신 정보를 쿼리하기 위해 데이터베이스의 일부 테이블이 매일 한 번만 업데이트됩니다.

그러나 :

  1. 데이터베이스가 매우 큰 네트워크 그래서 모든 쿼리는 초 정도 걸립니다, 느립니다.

  2. 우리는 각 쿼리 후에 복잡한 계산을 수행해야합니다.

  3. 많은 종류의 SQL 쿼리를 수행해야하므로 모든 SQL 쿼리의 결과를 저장하는 것이 현실적이지 않습니다.

  4. 디버깅 목적을 위해 매우 자주 계산 함수를 변경해야합니다.

느린 SQL 쿼리의 경우 모든 것이 너무 느립니다.

우리의 데이터는 매일 한 번만 업데이트되며 데이터베이스의 일부 쿼리는 매우 자주 사용됩니다.

그래서 자주 사용되는 SQL 쿼리와 중간 결과를 캐시하고 싶습니다.

Clojure의 memoize은 이러한 종류의 작업에 유용합니까? 두려운 것은 SQL 쿼리가 순수하지 않으므로 memoize은 결과를 캐시하지 않아야한다는 것입니다. 그러나 하루 동안 우리의 SQL 쿼리 결과는 동일해야합니다.

하루에 결과가 memoize 일 수 있으며 다음 날 자동으로 결과를 업데이트 할 수 있습니까?

도움 주셔서 감사합니다.

답변

6

대신 캐시를 사용해야합니다. 지. clojure.core.cache.

메모에 대해 명확히하기 : memoization은 순수한 함수에 도움이됩니다. 함수가 항상 같은 입력에 대해 동일한 출력을 반환하면 함수를 한 번 계산 한 후에 저장할 수 있습니다.

시간이 지남에 따라 출력이 변경되면 무효화해야합니다. 무효화 (그리고 기억 된 것의 크기와 같은 몇 가지 다른 문제)로 인한 메모 작성은 "캐싱"이라고합니다.

캐싱에 메모 메커니즘을 사용하는 경우 실제 수행중인 작업은 메모를 캐시에 구현하는 것입니다. 캐싱 라이브러리를 사용하는 것이 훨씬 적습니다.

이 경우 "자정에 무효화"와 같은 것을 구현해야합니다. 포인터를 얻는 방법은 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)))))) 
+0

clojure.core.memoize없는 이유는 무엇입니까? –

+0

코드 주셔서 감사합니다. 제가 실제로해야 할 일은 단지 우아한 방법 일뿐입니다. – cmal