From 8e87e344dc41601e2d8cc68e350d5f3f61ca1c00 Mon Sep 17 00:00:00 2001 From: cramakri <cramakri> Date: Tue, 4 May 2010 08:55:28 +0000 Subject: [PATCH] LMS-1153 Improved performance of query by using a sub-select to reduce the number of joins. SVN: 15741 --- .../authorization/PredicateExecutor.java | 33 +++++++++++-- .../DataSetCodeCollectionPredicate.java | 5 -- .../generic/shared/dto/DataSetAccessPE.java | 46 +++---------------- 3 files changed, 36 insertions(+), 48 deletions(-) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java index e5b64cd5724..32a166434b6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java @@ -16,6 +16,7 @@ package ch.systemsx.cisd.openbis.generic.server.authorization; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -272,13 +273,37 @@ public final class PredicateExecutor @SuppressWarnings("unchecked") public List<DataSetAccessPE> tryGetDatasetCollectionAccessData(List<String> dataSetCodes) { + Session sess = daoFactory.getSessionFactory().getCurrentSession(); Query query = sess.getNamedQuery(DataSetAccessPE.DATASET_ACCESS_QUERY_NAME); query = query.setReadOnly(true); - List<DataSetAccessPE> results = - query.setParameterList(DataSetAccessPE.DATA_SET_CODES_PARAMETER_NAME, - dataSetCodes).list(); - return results; + + // WORKAROUND Problem in Hibernate when the number of data set codes > 1000 + // Though this query runs quickly within the pgadmin tool, even for large numbers of + // data set codes, Hibernate becomes *very* slow when the size of the data set codes + // exceeds 1000. For that reason, break down the query into smaller sections and + // reassemble the results. + ArrayList<DataSetAccessPE> fullResults = new ArrayList<DataSetAccessPE>(); + + int size = dataSetCodes.size(); + // blockSize is a magic number -- I don't know what the optimal value is, but execution + // speed slows down if the blockSize > 1999 + int blockSize = 999; + int start, end; + + // Loop over the codes, one block at a time + for (start = 0, end = Math.min(start + blockSize, size); start < size; start = end, end = + Math.min(start + blockSize, size)) + { + List<String> sublist = dataSetCodes.subList(start, end); + query = + query.setParameterList(DataSetAccessPE.DATA_SET_CODES_PARAMETER_NAME, + sublist); + List<DataSetAccessPE> results = query.list(); + fullResults.addAll(results); + } + + return fullResults; } public GroupPE tryToGetGroup(SpaceOwnerKind kind, TechId techId) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodeCollectionPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodeCollectionPredicate.java index ed04d8340e0..dcd9c80d561 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodeCollectionPredicate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/authorization/predicate/DataSetCodeCollectionPredicate.java @@ -52,11 +52,6 @@ public class DataSetCodeCollectionPredicate extends AbstractGroupPredicate<List< return Status.OK; } - if (accessData.size() < dataSetCodes.size()) - { - return Status.createError("Could not get access data for all datasets"); - } - for (DataSetAccessPE accessDatum : accessData) { String dbInstanceUUID = accessDatum.getDatabaseInstanceUuid(); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java index 4a9ba8d9b27..479ca131da1 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetAccessPE.java @@ -31,25 +31,15 @@ import javax.persistence.SqlResultSetMapping; @Entity @SqlResultSetMapping(name = "implicit", entities = @EntityResult(entityClass = DataSetAccessPE.class)) @NamedNativeQuery(name = "dataset_access", query = "select " - + "ds.id as dataSetId, ds.code as dataSetCode, g.code as groupCode, dbi.uuid as databaseInstanceUuid, dbi.code as databaseInstanceCode " - + "from " - + TableNames.DATA_TABLE - + " ds, " - + TableNames.EXPERIMENTS_TABLE - + " e, " - + TableNames.PROJECTS_TABLE - + " p, " - + TableNames.GROUPS_TABLE - + " g, " - + TableNames.DATABASE_INSTANCES_TABLE - + " dbi " - + "where ds.code in (:codes) and e.id = ds.expe_id and p.id = e.proj_id and g.id = p.grou_id and dbi.id = g.dbin_id", resultSetMapping = "implicit") + + "g.code as groupCode, dbi.uuid as databaseInstanceUuid, dbi.code as databaseInstanceCode " + + "from " + TableNames.PROJECTS_TABLE + " p, " + TableNames.GROUPS_TABLE + " g, " + + TableNames.DATABASE_INSTANCES_TABLE + " dbi " + "where p.id in " + + "(select e.proj_id from " + TableNames.DATA_TABLE + " ds, " + + TableNames.EXPERIMENTS_TABLE + " e " + + "where ds.code in (:codes) and ds.expe_id = e.id group by e.proj_id) " + + "and p.grou_id = g.id and dbi.id = g.dbin_id", resultSetMapping = "implicit") public class DataSetAccessPE { - private String dataSetId; - - private String dataSetCode; - private String groupCode; private String databaseInstanceUuid; @@ -68,24 +58,12 @@ public class DataSetAccessPE String databaseInstanceCode) { DataSetAccessPE newMe = new DataSetAccessPE(); - newMe.setDataSetId(dataSetId); - newMe.setDataSetCode(dataSetCode); newMe.setGroupCode(groupCode); newMe.setDatabaseInstanceUuid(databaseInstanceUuid); newMe.setDatabaseInstanceCode(databaseInstanceCode); return newMe; } - void setDataSetId(String dataSetId) - { - this.dataSetId = dataSetId; - } - - void setDataSetCode(String dataSetCode) - { - this.dataSetCode = dataSetCode; - } - void setGroupCode(String groupCode) { this.groupCode = groupCode; @@ -102,16 +80,6 @@ public class DataSetAccessPE } @Id - public String getDataSetId() - { - return dataSetId; - } - - public String getDataSetCode() - { - return dataSetCode; - } - public String getGroupCode() { return groupCode; -- GitLab