30 개 항목 목록에서 3 개 요소의 가능한 모든 조합 목록을 가져 오려고합니다. 다음 코드를 사용하려고했지만 OutOfMemoryError
. 이것보다 더 효율적인 대안이 있습니까?
val items = sqlContext.table(SOURCE_DB + "." + SOURCE_TABLE).
select("item_id").distinct.cache
val items.take(1) // Compute cache before join
val itemCombinations = items.select($"item_id".alias("id_A")).
join(
items.select($"item_id".alias("id_B")), $"id_A".lt($"id_B")).
join(
items.select($"item_id".alias("id_C")), $"id_B".lt($"id_C"))
접근 방식은 괜찮아 보이지만 쿼리 실행 수준에서 상당한 오버 헤드를 생성 할 수 있습니다. n이 상당히 작은 숫자라고 가정하면 Scala 구현을 직접 사용할 수 있습니다.
val localItems = items.collect
val combinations = localItems.combinations(3)
그 결과 iterator
상당한 메모리 오버 헤드없이 한 번에 하나의 요소를 사용할 수 있습니다.
Spark 버전을 만들고자한다면 RDD 수준으로 떨어 뜨리면 쿼리 플래너 (문제가 있다고 가정)를 피할 수 있습니다. 이것은 기본적으로 질문의 조인과 동일한 표현입니다.
val items = sqlContext.table(SOURCE_DB + "." + SOURCE_TABLE).select("item_id").rdd
val combinations = items.cartesian(items).filter{case(x,y) => x<y}.cartesian(items).filter{case ((x,y),z) => y<z}
내 로컬 컴퓨터에서 동등한 코드 실행 :
val data = List.fill(1000)(scala.util.Random.nextInt(999))
val rdd = sparkContext.parallelize(data)
val combinations = rdd.cartesian(rdd).filter{case(x,y) => x<y}.cartesian(rdd).filter{case ((x,y),z) => y<z}
combinations.count
// res5: Long = 165623528
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다