Compare commits

..

2 Commits

Author SHA1 Message Date
joungmin
7411c8956f docs(changelog): v0.1.34 #331 VectorService batchUpdate 기록 2026-06-15 15:42:43 +09:00
joungmin
be302612f5 perf(vector): #331 VectorService.saveRestaurantVectors batchUpdate
- N+1 단건 jdbc.update → 단일 jdbc.batchUpdate(SqlParameterSource[])
- UUID 인라인 변환 → IdGenerator.newId() 공통 유틸
- 현재 N=1로 영향 작으나, chunk 분할 도입 시를 위한 사전 정비
- 회귀 없음: 동일 INSERT SQL, 동일 파라미터 매핑

설계서: docs/design/331-vector-batch-insert/README.md

Refs: #331 (Developer 단계)
2026-06-15 15:40:45 +09:00
2 changed files with 22 additions and 9 deletions

View File

@@ -6,6 +6,13 @@
## 2026-06-15 ## 2026-06-15
### ⚡ #331 VectorService batchUpdate (v0.1.34)
- saveRestaurantVectors: N+1 단건 INSERT → 단일 jdbc.batchUpdate(SqlParameterSource[])
- UUID 인라인 변환 제거 → IdGenerator.newId() 공통화
- 현재 N=1이지만 chunk 분할 도입 시 효과 본격화
- 설계서: docs/design/331-vector-batch-insert/README.md
- Refs: #331 (close)
### ⚡ #326 parseJson 단일 패스 (v0.1.33) ### ⚡ #326 parseJson 단일 패스 (v0.1.33)
- OciGenAiService.parseJson 잘린 배열 복구를 brace depth counter 단일 패스로 교체 - OciGenAiService.parseJson 잘린 배열 복구를 brace depth counter 단일 패스로 교체
- 이전 O(N²) + Jackson 예외 양산 → O(N) + 명시적 에러 경로 - 이전 O(N²) + Jackson 예외 양산 → O(N) + 명시적 에러 경로

View File

@@ -1,10 +1,12 @@
package com.tasteby.service; package com.tasteby.service;
import com.tasteby.util.IdGenerator;
import com.tasteby.util.JsonUtil; import com.tasteby.util.JsonUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
@@ -64,6 +66,9 @@ public class VectorService {
/** /**
* Save vector embeddings for a restaurant. * Save vector embeddings for a restaurant.
*
* #331 — N개 청크를 단일 batchUpdate 호출로 처리 (이전: N+1 INSERT round-trip).
* UUID 생성은 IdGenerator.newId() 공통 유틸 사용 (인라인 변환 코드 제거).
*/ */
public void saveRestaurantVectors(String restaurantId, List<String> chunks) { public void saveRestaurantVectors(String restaurantId, List<String> chunks) {
if (chunks.isEmpty()) return; if (chunks.isEmpty()) return;
@@ -75,19 +80,20 @@ public class VectorService {
VALUES (:id, :rid, :chunk, :emb) VALUES (:id, :rid, :chunk, :emb)
"""; """;
SqlParameterSource[] batch = new SqlParameterSource[chunks.size()];
for (int i = 0; i < chunks.size(); i++) { for (int i = 0; i < chunks.size(); i++) {
String id = UUID.randomUUID().toString().replace("-", "").substring(0, 32).toUpperCase(); List<Double> emb = embeddings.get(i);
float[] vec = new float[embeddings.get(i).size()]; float[] vec = new float[emb.size()];
for (int j = 0; j < vec.length; j++) { for (int j = 0; j < vec.length; j++) {
vec[j] = embeddings.get(i).get(j).floatValue(); vec[j] = emb.get(j).floatValue();
} }
var params = new MapSqlParameterSource(); batch[i] = new MapSqlParameterSource()
params.addValue("id", id); .addValue("id", IdGenerator.newId())
params.addValue("rid", restaurantId); .addValue("rid", restaurantId)
params.addValue("chunk", chunks.get(i)); .addValue("chunk", chunks.get(i))
params.addValue("emb", vec); .addValue("emb", vec);
jdbc.update(sql, params);
} }
jdbc.batchUpdate(sql, batch);
} }
/** /**