Skip to content

Commit a4c15d9

Browse files
Artemiy Degtyarevchrshnv
authored andcommitted
fix: more optimal pg query
Signed-off-by: Artemiy Degtyarev <[email protected]> Signed-off-by: Artemiy Chereshnevvv <[email protected]>
1 parent 3cc7938 commit a4c15d9

File tree

2 files changed

+28
-29
lines changed

2 files changed

+28
-29
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StatementFactory.java

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -238,47 +238,46 @@ Sort applyCriteriaOrderBy(Sort sort, @Nullable ScrollPosition scrollPosition) {
238238
}
239239

240240
Criteria applyScrollCriteria(Criteria criteria, @Nullable ScrollPosition position, Sort sort) {
241-
if (!(position instanceof KeysetScrollPosition) || position.isInitial() || ((KeysetScrollPosition) position).getKeys().isEmpty())
241+
if (!(position instanceof KeysetScrollPosition keyset)
242+
|| position.isInitial()
243+
|| keyset.getKeys().isEmpty()) {
242244
return criteria;
245+
}
243246

244-
Map<String, Object> keys = ((KeysetScrollPosition) position).getKeys();
247+
Map<String, Object> keys = keyset.getKeys();
245248
List<String> columns = new ArrayList<>(keys.keySet());
246249
List<Object> values = new ArrayList<>(keys.values());
247250

248-
Criteria result = null;
251+
Map<String, Sort.Direction> directions =
252+
sort.stream().collect(Collectors.toMap(Sort.Order::getProperty, Sort.Order::getDirection));
249253

250-
for (int i = 0; i < keys.size(); i++) {
251-
Map<String, Sort.Direction> orders =
252-
sort.get().collect(Collectors.toMap(Sort.Order::getProperty, Sort.Order::getDirection));
254+
String primary = columns.get(0);
255+
Object primaryValue = values.get(0);
253256

254-
Criteria.CriteriaStep orCriteriaStep = Criteria.where(columns.get(i));
255-
Criteria orCriteria;
257+
Criteria primaryCompare;
258+
Sort.Direction dir = directions.getOrDefault(primary, Sort.DEFAULT_DIRECTION);
256259

257-
Sort.Direction defaultDirection = orders.values().stream().findFirst().orElse(Sort.DEFAULT_DIRECTION);
258-
Sort.Direction curDirection = orders.get(columns.get(i));
260+
if (keyset.scrollsForward() ^ dir.isDescending()) {
261+
primaryCompare = Criteria.where(primary).greaterThanOrEquals(primaryValue);
262+
} else {
263+
primaryCompare = Criteria.where(primary).lessThanOrEquals(primaryValue);
264+
}
259265

260-
if (curDirection == null)
261-
curDirection = defaultDirection;
266+
Criteria tupleCompare = null;
267+
for (int i = 0; i < columns.size(); i++) {
268+
Criteria orCriteria;
269+
String col = columns.get(i);
270+
Object val = values.get(i);
262271

263-
if (((KeysetScrollPosition) position).scrollsForward()) {
264-
if (curDirection.isAscending())
265-
orCriteria = orCriteriaStep.greaterThan(values.get(i));
266-
else
267-
orCriteria = orCriteriaStep.lessThan(values.get(i));
268-
} else {
269-
if (curDirection.isAscending())
270-
orCriteria = orCriteriaStep.lessThan(values.get(i));
271-
else
272-
orCriteria = orCriteriaStep.greaterThan(values.get(i));
273-
}
272+
Sort.Direction colDir = directions.getOrDefault(col, dir);
273+
boolean asc = keyset.scrollsForward() ? colDir.isAscending() : colDir.isDescending();
274274

275-
for (int j = 0; j < i; j++)
276-
orCriteria = Criteria.where(columns.get(j)).is(values.get(j)).and(orCriteria);
275+
orCriteria = asc ? Criteria.where(col).greaterThan(val) : Criteria.where(col).lessThan(val);
277276

278-
result = (result == null) ? orCriteria : result.or(orCriteria);
277+
tupleCompare = (tupleCompare == null) ? orCriteria : tupleCompare.or(orCriteria);
279278
}
280279

281-
return criteria.and(result);
280+
return criteria.and(primaryCompare).and(tupleCompare);
282281
}
283282

284283
SelectBuilder.SelectOrdered applyOrderBy(Sort sort, RelationalPersistentEntity<?> entity, Table table,

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,8 +1559,8 @@ void queryByWindowKeySetTwoKeys() {
15591559
DummyEntity four = repository.save(createEntity("four", it -> it.setPointInTime(Instant.ofEpochSecond(4000))));
15601560
DummyEntity five = repository.save(createEntity("five", it -> it.setPointInTime(Instant.ofEpochSecond(5000))));
15611561

1562-
WindowIterator<DummyEntity> iter = WindowIterator.of(position -> repository.findFirst2ByOrderByIdPropDesc(position))
1563-
.startingAt(ScrollPosition.forward(Map.of("idProp", 5, "pointInTime", Instant.now())));
1562+
WindowIterator<DummyEntity> iter = WindowIterator.of(position -> repository.findFirst2ByOrderByIdPropAsc(position))
1563+
.startingAt(ScrollPosition.forward(Map.of("idProp", 1, "pointInTime", Instant.ofEpochSecond(1000))));
15641564

15651565
List<DummyEntity> entities = new ArrayList<>();
15661566
while (iter.hasNext())

0 commit comments

Comments
 (0)