I have simple showcase with ReactiveCrudRepository, which shows almost 2x difference in insertion speed using ReactiveCrudRepository.save() vs ReactiveCqlOperations.execute()
Here is the code:
Entity:
@Table("snapshot")
@Value
@Builder
@EqualsAndHashCode(callSuper = false)
@RequiredArgsConstructor
public class SnapshotRecord {
@PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED)
long id;
@PrimaryKeyColumn(ordinal = 1, type = PrimaryKeyType.PARTITIONED)
short market;
@PrimaryKeyColumn(ordinal = 3, type = PrimaryKeyType.CLUSTERED)
Instant slot;
double value;
}
Repository:
public interface SnapshotRepository extends ReactiveCrudRepository<SnapshotRecord, Long> {
default Mono<Boolean> saveViaCql(ReactiveCqlOperations cqlOps, SnapshotRecord record) {
return cqlOps.execute(
"INSERT INTO snapshot (id, market,slot,value) VALUES (?,?,?,?) USING TIMESTAMP ?;",
ps -> {
return ps.bind(
record.getId(),
record.getMarket(),
record.getSlot(),
record.getValue(),
record.getSlot().toEpochMilli() * 1000
);
}
);
}
}
Runner:
Flux<SnapshotRecord> data = Flux.generate(Object::new, (state, sink) -> {
ThreadLocalRandom random = ThreadLocalRandom.current();
sink.next(
new SnapshotRecord(
random.nextLong(),
(short) random.nextInt(),
Clock.systemUTC().instant(),
random.nextDouble()
)
);
return state;
});
subscription = data
//.flatMap((SnapshotRecord record) -> repository.saveViaCql(cqlOps, record), 512, 2048)
.flatMap(repository::save, 512, 2048) //doing this runs almost 2x slower than previous line
.doOnNext(d -> success.incrementAndGet())
.onErrorContinue((throwable, object) -> fail.incrementAndGet())
.subscribe();
Full project link on Github:
https://github.com/piddubnyi/spring-data-cassandra-performnace
Is there any way to improve insertion performance of repository.save(), or spring-proxy is really costly in this case?