Merge "Avoid multiple inner joins if dimensions specified"
This commit is contained in:
commit
c47154d279
@ -55,12 +55,12 @@ public class MeasurementVerticaRepoImpl implements MeasurementRepo {
|
||||
"select def.name, mes.definition_dimensions_id, defdims.dimension_set_id, defdims.definition_id, "
|
||||
+ "mes.time_stamp, mes.value, mes.value_meta "
|
||||
+ "from MonMetrics.Measurements mes, MonMetrics.Definitions def, MonMetrics.DefinitionDimensions defdims "
|
||||
+ "%s "
|
||||
+ "where mes.definition_dimensions_id = defdims.id "
|
||||
+ "and def.id = defdims.definition_id "
|
||||
+ "and def.tenant_id = :tenantId "
|
||||
+ "and mes.time_stamp >= :startTime "
|
||||
+ "%s "
|
||||
+ "%s " // metric name here
|
||||
+ "%s " // dimension and clause here
|
||||
+ "order by mes.time_stamp ASC "
|
||||
+ "limit :limit";
|
||||
|
||||
@ -114,8 +114,8 @@ public class MeasurementVerticaRepoImpl implements MeasurementRepo {
|
||||
|
||||
String sql =
|
||||
String.format(FIND_BY_METRIC_DEF_SQL,
|
||||
MetricQueries.buildJoinClauseFor(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON),
|
||||
sb);
|
||||
sb,
|
||||
MetricQueries.buildDimensionAndClause(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
|
||||
Query<Map<String, Object>> query =
|
||||
h.createQuery(sql)
|
||||
|
@ -48,37 +48,28 @@ public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
|
||||
+ "FROM MonMetrics.Definitions def, MonMetrics.DefinitionDimensions defDims "
|
||||
// Outer join needed in case there are no dimensions for a definition.
|
||||
+ "LEFT OUTER JOIN MonMetrics.Dimensions dims ON dims.dimension_set_id = defDims"
|
||||
+ ".dimension_set_id "
|
||||
+ "WHERE def.id = defDims.definition_id "
|
||||
+ "AND defDims.id IN (%s) "
|
||||
+ "ORDER BY defDims.id ASC ";
|
||||
|
||||
private static final String
|
||||
METRIC_DEFINITIONS_SUB_SELECT =
|
||||
"SELECT defDimsSub.id "
|
||||
+ "FROM MonMetrics.Definitions defSub, MonMetrics.DefinitionDimensions defDimsSub"
|
||||
+ "%s " // Dimensions inner join goes here if dimensions specified.
|
||||
+ "WHERE defDimsSub.definition_id = defSub.id "
|
||||
+ "AND defSub.tenant_id = :tenantId "
|
||||
+ ".dimension_set_id WHERE def.id = defDims.definition_id "
|
||||
+ "and def.tenant_id = :tenantId "
|
||||
+ "%s " // Name goes here.
|
||||
+ "%s " // Offset goes here.
|
||||
+ "ORDER BY defdimsSub.id ASC %s"; // Limit goes here.
|
||||
+ "%s " // Dimensions and clause goes here
|
||||
+ "ORDER BY defDims.id ASC %s"; // Limit goes here.
|
||||
|
||||
private static final String
|
||||
FIND_METRIC_NAMES_SQL =
|
||||
"SELECT distinct def.id, def.name "
|
||||
+ "FROM MonMetrics.Definitions def "
|
||||
+ "WHERE def.id IN (%s) "
|
||||
+ "WHERE def.id IN (%s) " // Subselect goes here
|
||||
+ "ORDER BY def.id ASC ";
|
||||
|
||||
private static final String
|
||||
METRIC_NAMES_SUB_SELECT =
|
||||
"SELECT defSub.id "
|
||||
+ "FROM MonMetrics.Definitions defSub, MonMetrics.DefinitionDimensions defDimsSub "
|
||||
+ "%s " // Dimensions inner join goes here if dimensions specified.
|
||||
+ "WHERE defDimsSub.definition_id = defSub.id "
|
||||
+ "AND defSub.tenant_id = :tenantId "
|
||||
+ "%s " // Offset goes here.
|
||||
+ "%s " // Dimensions and clause goes here
|
||||
+ "ORDER BY defSub.id ASC %s"; // Limit goes here.
|
||||
|
||||
private static final String TABLE_TO_JOIN_DIMENSIONS_ON = "defDimsSub";
|
||||
@ -136,11 +127,11 @@ public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
|
||||
// Can't bind limit in a nested sub query. So, just tack on as String.
|
||||
String limitPart = " limit " + Integer.toString(limit + 1);
|
||||
|
||||
String
|
||||
defSubSelect =
|
||||
String defSubSelect =
|
||||
String.format(METRIC_NAMES_SUB_SELECT,
|
||||
MetricQueries.buildJoinClauseFor(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON),
|
||||
offsetPart, limitPart);
|
||||
offsetPart,
|
||||
MetricQueries.buildDimensionAndClause(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON),
|
||||
limitPart);
|
||||
|
||||
String sql = String.format(FIND_METRIC_NAMES_SQL, defSubSelect);
|
||||
|
||||
@ -235,7 +226,7 @@ public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
|
||||
|
||||
if (name != null && !name.isEmpty()) {
|
||||
|
||||
namePart = " and defSub.name = :name ";
|
||||
namePart = " and def.name = :name ";
|
||||
|
||||
}
|
||||
|
||||
@ -243,20 +234,18 @@ public class MetricDefinitionVerticaRepoImpl implements MetricDefinitionRepo {
|
||||
|
||||
if (offset != null && !offset.isEmpty()) {
|
||||
|
||||
offsetPart = " and defdimsSub.id > :offset ";
|
||||
offsetPart = " and defDims.id > :offset ";
|
||||
|
||||
}
|
||||
|
||||
// Can't bind limit in a nested sub query. So, just tack on as String.
|
||||
String limitPart = " limit " + Integer.toString(limit + 1);
|
||||
|
||||
String
|
||||
defSubSelect =
|
||||
String.format(METRIC_DEFINITIONS_SUB_SELECT,
|
||||
MetricQueries.buildJoinClauseFor(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON),
|
||||
namePart, offsetPart, limitPart);
|
||||
|
||||
String sql = String.format(FIND_METRIC_DEFS_SQL, defSubSelect);
|
||||
String sql =
|
||||
String.format(FIND_METRIC_DEFS_SQL,
|
||||
namePart, offsetPart,
|
||||
MetricQueries.buildDimensionAndClause(dimensions, "defDims"),
|
||||
limitPart);
|
||||
|
||||
try (Handle h = db.open()) {
|
||||
|
||||
|
@ -26,38 +26,33 @@ import monasca.common.persistence.SqlQueries;
|
||||
final class MetricQueries {
|
||||
private MetricQueries() {}
|
||||
|
||||
static String buildJoinClauseFor(Map<String, String> dimensions, String tableToJoinName) {
|
||||
static String buildDimensionAndClause(Map<String, String> dimensions, String tableToJoinName) {
|
||||
|
||||
StringBuilder sb = null;
|
||||
|
||||
if (dimensions != null) {
|
||||
if (dimensions != null && dimensions.size() > 0) {
|
||||
|
||||
int numDims = dimensions.size();
|
||||
sb = new StringBuilder();
|
||||
sb.append(" and " + tableToJoinName + ".dimension_set_id in ")
|
||||
.append("(select dimension_set_id from MonMetrics.Dimensions where ");
|
||||
|
||||
for (int i = 0; i < dimensions.size(); i++) {
|
||||
|
||||
sb
|
||||
.append(" inner join MonMetrics.Dimensions dim")
|
||||
for (int i = 0; i < numDims; i++) {
|
||||
sb.append("name = :dname")
|
||||
.append(i)
|
||||
.append(" on dim")
|
||||
.append(i)
|
||||
.append(".name = :dname")
|
||||
.append(i)
|
||||
.append(" and dim")
|
||||
.append(i)
|
||||
.append(".value = " + ":dvalue")
|
||||
.append(i)
|
||||
.append(" and " + tableToJoinName + ".dimension_set_id = dim")
|
||||
.append(i)
|
||||
.append(".dimension_set_id");
|
||||
.append(" and value = :dvalue")
|
||||
.append(i);
|
||||
if (i != (numDims - 1)) {
|
||||
sb.append(" or ");
|
||||
}
|
||||
}
|
||||
sb.append(" group by dimension_set_id ")
|
||||
.append(" having count(*) = " + numDims +") ");
|
||||
}
|
||||
|
||||
return sb == null ? "" : sb.toString();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static Map<String, String> dimensionsFor(Handle handle, byte[] dimensionSetId) {
|
||||
|
||||
return SqlQueries.keyValuesFor(handle, "select name, value from MonMetrics.Dimensions "
|
||||
|
@ -52,9 +52,9 @@ public class StatisticVerticaRepoImpl implements StatisticRepo {
|
||||
"select defdims.id, def.name, d.name as dname, d.value as dvalue "
|
||||
+ "from MonMetrics.Definitions def, MonMetrics.DefinitionDimensions defdims "
|
||||
+ "left outer join MonMetrics.Dimensions d on d.dimension_set_id = defdims.dimension_set_id "
|
||||
+ "%s "
|
||||
+ "where def.id = defdims.definition_id and def.tenant_id = :tenantId "
|
||||
+ "%s "
|
||||
+ "%s " // metric name here
|
||||
+ "%s " // dimension and clause here
|
||||
+ "order by defdims.id ASC";
|
||||
|
||||
private static final String TABLE_TO_JOIN_DIMENSIONS_ON = "defdims";
|
||||
@ -208,8 +208,8 @@ public class StatisticVerticaRepoImpl implements StatisticRepo {
|
||||
String sql =
|
||||
String
|
||||
.format(FIND_BY_METRIC_DEF_SQL,
|
||||
MetricQueries.buildJoinClauseFor(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON),
|
||||
sb);
|
||||
sb,
|
||||
MetricQueries.buildDimensionAndClause(dimensions, TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
|
||||
Query<Map<String, Object>> query =
|
||||
h.createQuery(sql)
|
||||
|
@ -26,30 +26,29 @@ public class MetricQueriesTest {
|
||||
|
||||
private final static String TABLE_TO_JOIN_DIMENSIONS_ON = "defdims";
|
||||
|
||||
public void metricQueriesBuildJoinClauseForTest1() {
|
||||
public void metricQueriesBuildDimensionAndClauseTest1() {
|
||||
String expectedResult =
|
||||
" inner join MonMetrics.Dimensions dim0 on dim0.name = :dname0 and dim0" + ".value "
|
||||
+ "= :dvalue0 and defdims.dimension_set_id = dim0.dimension_set_id inner join "
|
||||
+ "MonMetrics.Dimensions dim1 on dim1.name = :dname1 and dim1.value = :dvalue1 and defdims"
|
||||
+ ".dimension_set_id = dim1.dimension_set_id";
|
||||
" and defdims.dimension_set_id in (select dimension_set_id from MonMetrics.Dimensions "
|
||||
+ "where name = :dname0 and value = :dvalue0 or name = :dname1 and value = :dvalue1 "
|
||||
+ "group by dimension_set_id having count(*) = 2) ";
|
||||
|
||||
Map<String, String> dimsMap = new HashMap<>();
|
||||
dimsMap.put("foo", "bar");
|
||||
dimsMap.put("biz", "baz");
|
||||
|
||||
String s = MetricQueries.buildJoinClauseFor(dimsMap, TABLE_TO_JOIN_DIMENSIONS_ON);
|
||||
String s = MetricQueries.buildDimensionAndClause(dimsMap, TABLE_TO_JOIN_DIMENSIONS_ON);
|
||||
assertEquals(expectedResult, s);
|
||||
}
|
||||
|
||||
public void metricQueriesBuildJoinClauseForTest2() {
|
||||
public void metricQueriesBuildDimensionAndClauseTest2() {
|
||||
String expectedResult = "";
|
||||
Map<String, String> dimsMap = new HashMap<>();
|
||||
assertEquals(expectedResult, MetricQueries.buildJoinClauseFor(dimsMap,TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
assertEquals(expectedResult, MetricQueries.buildDimensionAndClause(dimsMap,TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
}
|
||||
|
||||
public void metricQueriesBuildJoinClauseForTest3() {
|
||||
public void metricQueriesBuildDimensionAndClauseForTest3() {
|
||||
String expectedResult = "";
|
||||
Map<String, String> dimsMap = null;
|
||||
assertEquals(expectedResult, MetricQueries.buildJoinClauseFor(dimsMap, TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
assertEquals(expectedResult, MetricQueries.buildDimensionAndClause(dimsMap, TABLE_TO_JOIN_DIMENSIONS_ON));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user