2017-11-19 19 views
2

나는 풀고 싶은 가상의 상황이 있지만 이상적인 대답을 찾을 수 없습니다. 쿼리에서 반환 할 수있는 거대한 데이터 세트가 있다고 가정하고 메모리에 미치는 영향이 최소화되도록 페이지를 어떻게 매깁니까? datoms API, 데이터를 반복하고 하나씩 필터링 하시겠습니까? index-range API하지만 datoms API에서와 동일한 작업을 수행해야하며 항목을 반복하고 하나씩 필터링해야합니까? ID 만 반환하는 초기 쿼리를 수행하고, 다른 쿼리에서 전체 데이터 집합을 검색하는 데 사용할 수 있도록 해당 ID에 페이지 매기기를 수행합니다.Datomic에서 쿼리 결과 페이지 매기기

SELECT col1, col2, ... 
FROM ... 
WHERE ... 
ORDER BY -- this is a MUST there must be ORDER BY statement 
-- the paging comes here 
OFFSET  10 ROWS  -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

답변

5

많은 사항을 고려해야합니다.

먼저, Datomic과 함께 제공되는 Datalog 구현은 열망하고 디스크로 유출되지 않으므로 Datalog 쿼리의 결과 집합이 메모리에 적합해야합니다.

이것은 각 데이터 로그 쿼리가 데이터의 작은 부분 만 처리 할 수 ​​있기 때문에 Datalog가 큰 결과와 호환되지 않는다는 것을 의미하지는 않습니다. 예를 들어 Datalog를 사용하여 쿼리의 '논리적 인'부분 (반환 할 엔터티)과 Entity API 또는 Pull API를 사용하여 쿼리의 'content'부분을 (느리게) 계산할 수 있습니다 각 엔티티에 대해). 엔티티 ID가 Java Long (8 바이트) 일 뿐이므로 메모리 풋 프린트의 두 자리수 중 하나를 절약 할 수 있습니다. 엔터티 API를 사용하여 예 : 열심히 보조 BLOB 저장소에 전체 결과를 저장하여이 방법을 보완, 다음 페이지 매기기에 그에 대해 폴링 할 수 있습니다

(defn export-customers 
    [db search-criteria] 
    (->> 
    ;; logical part - Datalog-based, eager 
    (d/q '[:find [?customer ...] :in % $ ?search-criteria :where 
      (customer-matches-criteria ?search-criteria ?customer)] 
     (my-rules) db search-criteria) 
    ;; content part - Entity API based, lazy 
    (map (fn [eid] 
      (let [customer (d/entity db eid)] 
      (select-keys customer 
       [:customer/id 
       :customer/email 
       :customer/firstName 
       :customer/lastName 
       :customer/subscription-time])))) 
    )) 

.

쿼리 로직이 너무 복잡하지 않은 경우, 예를 들어 원시 인덱스 액세스 (예 : Datoms API 또는 인덱스 범위 API 사용)를 게으른 방식으로 사용하는 등 Datalog를 사용하지 않을 수도 있습니다.

마지막으로 Datomic이 분석 쿼리를 처리하는 데 적합하지 않을 수도 있습니다. Datomic을 사용하면 변경 탐지가 쉽지 않으므로 분석 쿼리 (예 : ElasticSearch, Google BigQuery, PostgreSQL 등)를 계산할 수있는 보조 저장소로 파생 데이터를 스트리밍하는 것이 매우 쉽습니다.

0

가이 페이지를 본 적이 : 당신은 일반적으로 쿼리 자체에 페이지 매김을 정의 할 수 있습니다 SQL에서

http://docs.datomic.com/query.html#memory-usage

모든 중간 결과가 메모리에 맞아야 말을 보인다. 나는 이것이 최종 결과에도 적용된다고 가정합니다.

당신은에 이상 물어 시도 할 수 있습니다 : https://forum.datomic.com/


사이드 참고 : Datomic 반품 및 엔티티, 명시 적으로 완전히 표시되지는 콘크리트한다 "게으른지도"의 한 형태이다

(let [plain-map (into {} entity-map) ] 
    (println plain-map)) 
+1

또한 '(datomic.api/REPL에서 엔티티를 검사 할 수 있습니다. 'into '와의 차이점은'touch '가 일반 Clojure 맵이 아니라 (채워진) Entity를 반환한다는 것입니다. –