Add DAO setting to specify maximum query size
This commit is contained in:
parent
69849dd3c5
commit
d40c5fa5e3
|
@ -104,7 +104,7 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
|
||||||
|
|
||||||
TypedQuery<Long> q = myEntityManager.createQuery("SELECT t.myId FROM ResourceTable t WHERE t.myIndexStatus IS NULL", Long.class);
|
TypedQuery<Long> q = myEntityManager.createQuery("SELECT t.myId FROM ResourceTable t WHERE t.myIndexStatus IS NULL", Long.class);
|
||||||
|
|
||||||
ourLog.info("Beginning indexing query with maximum {}", maxResult);
|
ourLog.debug("Beginning indexing query with maximum {}", maxResult);
|
||||||
q.setMaxResults(maxResult);
|
q.setMaxResults(maxResult);
|
||||||
Collection<Long> resources = q.getResultList();
|
Collection<Long> resources = q.getResultList();
|
||||||
|
|
||||||
|
@ -145,9 +145,14 @@ public abstract class BaseHapiFhirSystemDao<T, MT> extends BaseHapiFhirDao<IBase
|
||||||
}
|
}
|
||||||
|
|
||||||
long delay = System.currentTimeMillis() - start;
|
long delay = System.currentTimeMillis() - start;
|
||||||
long avg = count > 0 ? (delay / count) : 0;
|
long avg;
|
||||||
ourLog.info("Indexed {} resources in {}ms - Avg {}ms / resource", new Object[] { count, delay, avg });
|
if (count > 0) {
|
||||||
|
avg = (delay / count);
|
||||||
|
ourLog.info("Indexed {} resources in {}ms - Avg {}ms / resource", new Object[] { count, delay, avg });
|
||||||
|
} else {
|
||||||
|
ourLog.debug("Indexed 0 resources in {}ms", delay);
|
||||||
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,21 +64,21 @@ public class DaoConfig {
|
||||||
*/
|
*/
|
||||||
public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE;
|
public static final Long DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS = DateUtils.MILLIS_PER_MINUTE;
|
||||||
|
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private boolean myAllowExternalReferences = false;
|
private boolean myAllowExternalReferences = false;
|
||||||
|
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private boolean myAllowInlineMatchUrlReferences = true;
|
private boolean myAllowInlineMatchUrlReferences = true;
|
||||||
private boolean myAllowMultipleDelete;
|
private boolean myAllowMultipleDelete;
|
||||||
private boolean myDefaultSearchParamsCanBeOverridden = false;
|
private boolean myDefaultSearchParamsCanBeOverridden = false;
|
||||||
|
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private int myDeferIndexingForCodesystemsOfSize = 2000;
|
private int myDeferIndexingForCodesystemsOfSize = 2000;
|
||||||
|
|
||||||
private boolean myDeleteStaleSearches = true;
|
private boolean myDeleteStaleSearches = true;
|
||||||
|
@ -87,27 +87,34 @@ public class DaoConfig {
|
||||||
|
|
||||||
private boolean myEnforceReferentialIntegrityOnWrite = true;
|
private boolean myEnforceReferentialIntegrityOnWrite = true;
|
||||||
|
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
|
private long myExpireSearchResultsAfterMillis = DateUtils.MILLIS_PER_HOUR;
|
||||||
private int myHardTagListLimit = 1000;
|
/**
|
||||||
|
* update setter javadoc if default changes
|
||||||
|
*/
|
||||||
|
private Integer myFetchSizeDefaultMaximum = null;
|
||||||
|
|
||||||
|
private int myHardTagListLimit = 1000;
|
||||||
private int myIncludeLimit = 2000;
|
private int myIncludeLimit = 2000;
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private boolean myIndexContainedResources = true;
|
private boolean myIndexContainedResources = true;
|
||||||
private List<IServerInterceptor> myInterceptors;
|
private List<IServerInterceptor> myInterceptors;
|
||||||
// ***
|
/**
|
||||||
// update setter javadoc if default changes
|
* update setter javadoc if default changes
|
||||||
// ***
|
*/
|
||||||
private int myMaximumExpansionSize = 5000;
|
private int myMaximumExpansionSize = 5000;
|
||||||
private int myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION;
|
private int myMaximumSearchResultCountInTransaction = DEFAULT_MAXIMUM_SEARCH_RESULT_COUNT_IN_TRANSACTION;
|
||||||
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
private ResourceEncodingEnum myResourceEncoding = ResourceEncodingEnum.JSONC;
|
||||||
private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
|
private Long myReuseCachedSearchResultsForMillis = DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
|
||||||
private boolean mySchedulingDisabled;
|
private boolean mySchedulingDisabled;
|
||||||
private boolean mySubscriptionEnabled;
|
private boolean mySubscriptionEnabled;
|
||||||
|
/**
|
||||||
|
* update setter javadoc if default changes
|
||||||
|
*/
|
||||||
private long mySubscriptionPollDelay = 1000;
|
private long mySubscriptionPollDelay = 1000;
|
||||||
private Long mySubscriptionPurgeInactiveAfterMillis;
|
private Long mySubscriptionPurgeInactiveAfterMillis;
|
||||||
private boolean mySuppressUpdatesWithNoChange = true;
|
private boolean mySuppressUpdatesWithNoChange = true;
|
||||||
|
@ -160,6 +167,20 @@ public class DaoConfig {
|
||||||
return myExpireSearchResultsAfterMillis;
|
return myExpireSearchResultsAfterMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default maximum number of results to load in a query.
|
||||||
|
* <p>
|
||||||
|
* For example, if the database has a million Patient resources in it, and
|
||||||
|
* the client requests <code>GET /Patient</code>, if this value is set
|
||||||
|
* to a non-null value (default is <code>null</code>) only this number
|
||||||
|
* of results will be fetched. Setting this value appropriately
|
||||||
|
* can be useful to improve performance in some situations.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public Integer getFetchSizeDefaultMaximum() {
|
||||||
|
return myFetchSizeDefaultMaximum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum number of results to return in a GetTags query (DSTU1 only)
|
* Gets the maximum number of results to return in a GetTags query (DSTU1 only)
|
||||||
*/
|
*/
|
||||||
|
@ -549,6 +570,20 @@ public class DaoConfig {
|
||||||
myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis;
|
myExpireSearchResultsAfterMillis = theExpireSearchResultsAfterMillis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default maximum number of results to load in a query.
|
||||||
|
* <p>
|
||||||
|
* For example, if the database has a million Patient resources in it, and
|
||||||
|
* the client requests <code>GET /Patient</code>, if this value is set
|
||||||
|
* to a non-null value (default is <code>null</code>) only this number
|
||||||
|
* of results will be fetched. Setting this value appropriately
|
||||||
|
* can be useful to improve performance in some situations.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public void setFetchSizeDefaultMaximum(Integer theFetchSizeDefaultMaximum) {
|
||||||
|
myFetchSizeDefaultMaximum = theFetchSizeDefaultMaximum;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not call this method, it exists only for legacy reasons. It
|
* Do not call this method, it exists only for legacy reasons. It
|
||||||
* will be removed in a future version. Configure the page size on your
|
* will be removed in a future version. Configure the page size on your
|
||||||
|
|
|
@ -82,8 +82,7 @@ import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallback;
|
import org.springframework.transaction.support.TransactionCallback;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
|
||||||
|
@ -130,6 +129,7 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
@Before
|
@Before
|
||||||
public void beforeDisableResultReuse() {
|
public void beforeDisableResultReuse() {
|
||||||
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
|
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
|
||||||
|
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1852,6 +1852,22 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
assertThat(patients, not(containsInAnyOrder(pid2)));
|
assertThat(patients, not(containsInAnyOrder(pid2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithFetchSizeDefaultMaximum() {
|
||||||
|
myDaoConfig.setFetchSizeDefaultMaximum(5);
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
Patient p = new Patient();
|
||||||
|
p.addName().setFamily("PT" + i);
|
||||||
|
myPatientDao.create(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchParameterMap map = new SearchParameterMap();
|
||||||
|
map.setLoadSynchronous(true);
|
||||||
|
IBundleProvider values = myPatientDao.search(map);
|
||||||
|
assertEquals(5, values.size().intValue());
|
||||||
|
assertEquals(5, values.getResources(0, 1000).size());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchStringParam() throws Exception {
|
public void testSearchStringParam() throws Exception {
|
||||||
|
|
|
@ -28,6 +28,13 @@
|
||||||
Optimize queries in JPA server remove a few redundant select columns when performing
|
Optimize queries in JPA server remove a few redundant select columns when performing
|
||||||
searches. This provides a slight speed increase in some cases.
|
searches. This provides a slight speed increase in some cases.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Add configuration to JPA server DaoConfig that allows a maximum
|
||||||
|
number of search results to be specified. Queries will never return
|
||||||
|
more than this number, which can be good for avoiding accidental
|
||||||
|
performance problems in situations where lare queries should not be
|
||||||
|
needed
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.5" date="2017-06-08">
|
<release version="2.5" date="2017-06-08">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue