mirror of
https://github.com/corda/corda.git
synced 2025-05-29 13:44:25 +00:00
CORDA-3176 Inefficient query generated on vault queries with custom p… (#6241)
* CORDA-3176 Inefficient query generated on vault queries with custom paging a check added to avoid self joins local postgres db tests were executed on large volume test data (50k states) to ensure that the DB optimizes the suspicious query and so it does not cuase performance issues. A test added to check that a pagination query on large volume of sorted data is completed in a reasonable time * foreach detekt fix
This commit is contained in:
parent
14b9bc2c53
commit
9c4a76d367
@ -612,12 +612,15 @@ class HibernateQueryCriteriaParser(val contractStateType: Class<out ContractStat
|
|||||||
entityRoot
|
entityRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
val joinPredicate = if(IndirectStatePersistable::class.java.isAssignableFrom(entityRoot.javaType)) {
|
if (entityRoot != vaultStates){ // to avoid self join
|
||||||
criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), entityRoot.get<IndirectStatePersistable<*>>("compositeKey").get<PersistentStateRef>("stateRef"))
|
val joinPredicate = if(IndirectStatePersistable::class.java.isAssignableFrom(entityRoot.javaType)) {
|
||||||
} else {
|
criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), entityRoot.get<IndirectStatePersistable<*>>("compositeKey").get<PersistentStateRef>("stateRef"))
|
||||||
criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), entityRoot.get<PersistentStateRef>("stateRef"))
|
}
|
||||||
|
else {
|
||||||
|
criteriaBuilder.equal(vaultStates.get<PersistentStateRef>("stateRef"), entityRoot.get<PersistentStateRef>("stateRef"))
|
||||||
|
}
|
||||||
|
predicateSet.add(joinPredicate)
|
||||||
}
|
}
|
||||||
predicateSet.add(joinPredicate)
|
|
||||||
|
|
||||||
// resolve general criteria expressions
|
// resolve general criteria expressions
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@ -501,6 +501,40 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
|
|||||||
assertThat(queriedStates).containsExactlyElementsOf(allStates)
|
assertThat(queriedStates).containsExactlyElementsOf(allStates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout=300_000)
|
||||||
|
fun `query with sort criteria and pagination on large volume of states should complete in time`() {
|
||||||
|
val numberOfStates = 1000
|
||||||
|
val pageSize = 1000
|
||||||
|
|
||||||
|
for (i in 1..50) {
|
||||||
|
database.transaction {
|
||||||
|
vaultFiller.fillWithSomeTestLinearStates(numberOfStates, linearNumber = 100L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val criteria = VaultQueryCriteria(status = Vault.StateStatus.ALL)
|
||||||
|
|
||||||
|
val sortAttribute = SortAttribute.Custom(DummyLinearStateSchemaV1.PersistentDummyLinearState::class.java, "stateRef")
|
||||||
|
|
||||||
|
Sort.Direction.values().forEach { sortDirection ->
|
||||||
|
|
||||||
|
val sorting = Sort(listOf(Sort.SortColumn(sortAttribute, sortDirection)))
|
||||||
|
|
||||||
|
val start = System.currentTimeMillis()
|
||||||
|
val queriedStates = mutableListOf<StateAndRef<*>>()
|
||||||
|
var pageNumber = 0
|
||||||
|
while (pageNumber * pageSize < numberOfStates) {
|
||||||
|
val paging = PageSpecification(pageNumber = pageNumber + 1, pageSize = pageSize)
|
||||||
|
val page = vaultService.queryBy<DummyLinearContract.State>(sorting = sorting, paging = paging, criteria = criteria)
|
||||||
|
queriedStates += page.states
|
||||||
|
pageNumber++
|
||||||
|
}
|
||||||
|
|
||||||
|
val elapsed = System.currentTimeMillis() - start
|
||||||
|
assertThat(elapsed).isLessThan(1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test(timeout=300_000)
|
@Test(timeout=300_000)
|
||||||
fun `unconsumed states with count`() {
|
fun `unconsumed states with count`() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user