Commit 374cf2a14c311d9bab6f852e2bc083af24c066ec

Authored by Andrii Shvaika
1 parent 8c0ae686

Performance improvement

@@ -261,8 +261,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -261,8 +261,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
261 .collect(Collectors.toList()); 261 .collect(Collectors.toList());
262 List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest()) 262 List<EntityKeyMapping> entityFieldsFiltersMapping = filterMapping.stream().filter(mapping -> !mapping.isLatest())
263 .collect(Collectors.toList()); 263 .collect(Collectors.toList());
264 - List<EntityKeyMapping> latestFiltersMapping = filterMapping.stream().filter(EntityKeyMapping::isLatest)  
265 - .collect(Collectors.toList());  
266 264
267 List<EntityKeyMapping> allLatestMappings = mappings.stream().filter(EntityKeyMapping::isLatest) 265 List<EntityKeyMapping> allLatestMappings = mappings.stream().filter(EntityKeyMapping::isLatest)
268 .collect(Collectors.toList()); 266 .collect(Collectors.toList());
@@ -271,7 +269,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -271,7 +269,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
271 String entityWhereClause = DefaultEntityQueryRepository.this.buildEntityWhere(ctx, query.getEntityFilter(), entityFieldsFiltersMapping); 269 String entityWhereClause = DefaultEntityQueryRepository.this.buildEntityWhere(ctx, query.getEntityFilter(), entityFieldsFiltersMapping);
272 String latestJoinsCnt = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, true); 270 String latestJoinsCnt = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, true);
273 String latestJoinsData = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, false); 271 String latestJoinsData = EntityKeyMapping.buildLatestJoins(ctx, query.getEntityFilter(), entityType, allLatestMappings, false);
274 - String whereClause = DefaultEntityQueryRepository.this.buildWhere(ctx, latestFiltersMapping, query.getEntityFilter().getType());  
275 String textSearchQuery = DefaultEntityQueryRepository.this.buildTextSearchQuery(ctx, selectionMapping, pageLink.getTextSearch()); 272 String textSearchQuery = DefaultEntityQueryRepository.this.buildTextSearchQuery(ctx, selectionMapping, pageLink.getTextSearch());
276 String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType); 273 String entityFieldsSelection = EntityKeyMapping.buildSelections(entityFieldsSelectionMapping, query.getEntityFilter().getType(), entityType);
277 String entityTypeStr; 274 String entityTypeStr;
@@ -291,22 +288,20 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -291,22 +288,20 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
291 topSelection = topSelection + ", " + latestSelection; 288 topSelection = topSelection + ", " + latestSelection;
292 } 289 }
293 290
294 - String fromClauseCount = String.format("from (select %s from (select %s from %s e where %s) entities %s %s) result %s", 291 + String fromClauseCount = String.format("from (select %s from (select %s from %s e where %s) entities %s ) result %s",
295 "entities.*", 292 "entities.*",
296 entityFieldsSelection, 293 entityFieldsSelection,
297 addEntityTableQuery(ctx, query.getEntityFilter()), 294 addEntityTableQuery(ctx, query.getEntityFilter()),
298 entityWhereClause, 295 entityWhereClause,
299 latestJoinsCnt, 296 latestJoinsCnt,
300 - whereClause,  
301 textSearchQuery); 297 textSearchQuery);
302 298
303 - String fromClauseData = String.format("from (select %s from (select %s from %s e where %s) entities %s %s) result %s", 299 + String fromClauseData = String.format("from (select %s from (select %s from %s e where %s) entities %s ) result %s",
304 topSelection, 300 topSelection,
305 entityFieldsSelection, 301 entityFieldsSelection,
306 addEntityTableQuery(ctx, query.getEntityFilter()), 302 addEntityTableQuery(ctx, query.getEntityFilter()),
307 entityWhereClause, 303 entityWhereClause,
308 latestJoinsData, 304 latestJoinsData,
309 - whereClause,  
310 textSearchQuery); 305 textSearchQuery);
311 306
312 if (!StringUtils.isEmpty(pageLink.getTextSearch())) { 307 if (!StringUtils.isEmpty(pageLink.getTextSearch())) {
@@ -547,15 +542,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -547,15 +542,6 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
547 return from; 542 return from;
548 } 543 }
549 544
550 - private String buildWhere(QueryContext ctx, List<EntityKeyMapping> latestFiltersMapping, EntityFilterType filterType) {  
551 - String latestFilters = EntityKeyMapping.buildQuery(ctx, latestFiltersMapping, filterType);  
552 - if (!StringUtils.isEmpty(latestFilters)) {  
553 - return String.format("where %s", latestFilters);  
554 - } else {  
555 - return "";  
556 - }  
557 - }  
558 -  
559 private String buildTextSearchQuery(QueryContext ctx, List<EntityKeyMapping> selectionMapping, String searchText) { 545 private String buildTextSearchQuery(QueryContext ctx, List<EntityKeyMapping> selectionMapping, String searchText) {
560 if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) { 546 if (!StringUtils.isEmpty(searchText) && !selectionMapping.isEmpty()) {
561 String lowerSearchText = searchText.toLowerCase() + "%"; 547 String lowerSearchText = searchText.toLowerCase() + "%";
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 package org.thingsboard.server.dao.sql.query; 16 package org.thingsboard.server.dao.sql.query;
17 17
18 import lombok.Data; 18 import lombok.Data;
  19 +import org.springframework.util.StringUtils;
19 import org.thingsboard.server.common.data.DataConstants; 20 import org.thingsboard.server.common.data.DataConstants;
20 import org.thingsboard.server.common.data.EntityType; 21 import org.thingsboard.server.common.data.EntityType;
21 import org.thingsboard.server.common.data.query.BooleanFilterPredicate; 22 import org.thingsboard.server.common.data.query.BooleanFilterPredicate;
@@ -224,7 +225,7 @@ public class EntityKeyMapping { @@ -224,7 +225,7 @@ public class EntityKeyMapping {
224 return keyFilters.stream().map(keyFilter -> 225 return keyFilters.stream().map(keyFilter ->
225 this.buildKeyQuery(ctx, keyAlias, keyFilter, filterType)); 226 this.buildKeyQuery(ctx, keyAlias, keyFilter, filterType));
226 } else { 227 } else {
227 - return null; 228 + return Stream.empty();
228 } 229 }
229 } 230 }
230 231
@@ -236,15 +237,22 @@ public class EntityKeyMapping { @@ -236,15 +237,22 @@ public class EntityKeyMapping {
236 entityTypeStr = "'" + entityType.name() + "'"; 237 entityTypeStr = "'" + entityType.name() + "'";
237 } 238 }
238 ctx.addStringParameter(alias + "_key_id", entityKey.getKey()); 239 ctx.addStringParameter(alias + "_key_id", entityKey.getKey());
  240 + String filterQuery = toQueries(ctx, entityFilter.getType()).filter(Objects::nonNull).collect(
  241 + Collectors.joining(" and "));
  242 + if (StringUtils.isEmpty(filterQuery)) {
  243 + filterQuery = "";
  244 + } else {
  245 + filterQuery = " AND (" + filterQuery + ")";
  246 + }
239 if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) { 247 if (entityKey.getType().equals(EntityKeyType.TIME_SERIES)) {
240 String join = hasFilter() ? "left join" : "left outer join"; 248 String join = hasFilter() ? "left join" : "left outer join";
241 - return String.format("%s ts_kv_latest %s ON %s.entity_id=entities.id AND %s.key = (select key_id from ts_kv_dictionary where key = :%s_key_id)",  
242 - join, alias, alias, alias, alias); 249 + return String.format("%s ts_kv_latest %s ON %s.entity_id=entities.id AND %s.key = (select key_id from ts_kv_dictionary where key = :%s_key_id) %s",
  250 + join, alias, alias, alias, alias, filterQuery);
243 } else { 251 } else {
244 String query; 252 String query;
245 if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) { 253 if (!entityKey.getType().equals(EntityKeyType.ATTRIBUTE)) {
246 String join = hasFilter() ? "left join" : "left outer join"; 254 String join = hasFilter() ? "left join" : "left outer join";
247 - query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id", 255 + query = String.format("%s attribute_kv %s ON %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id ",
248 join, alias, alias, alias, entityTypeStr, alias, alias); 256 join, alias, alias, alias, entityTypeStr, alias, alias);
249 String scope; 257 String scope;
250 if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) { 258 if (entityKey.getType().equals(EntityKeyType.CLIENT_ATTRIBUTE)) {
@@ -254,12 +262,12 @@ public class EntityKeyMapping { @@ -254,12 +262,12 @@ public class EntityKeyMapping {
254 } else { 262 } else {
255 scope = DataConstants.SERVER_SCOPE; 263 scope = DataConstants.SERVER_SCOPE;
256 } 264 }
257 - query = String.format("%s AND %s.attribute_type='%s'", query, alias, scope); 265 + query = String.format("%s AND %s.attribute_type='%s' %s", query, alias, scope, filterQuery);
258 } else { 266 } else {
259 String join = hasFilter() ? "join LATERAL" : "left join LATERAL"; 267 String join = hasFilter() ? "join LATERAL" : "left join LATERAL";
260 - query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id " + 268 + query = String.format("%s (select * from attribute_kv %s WHERE %s.entity_id=entities.id AND %s.entity_type=%s AND %s.attribute_key=:%s_key_id %s " +
261 "ORDER BY %s.last_update_ts DESC limit 1) as %s ON true", 269 "ORDER BY %s.last_update_ts DESC limit 1) as %s ON true",
262 - join, alias, alias, alias, entityTypeStr, alias, alias, alias, alias); 270 + join, alias, alias, alias, entityTypeStr, alias, alias, filterQuery, alias, alias);
263 } 271 }
264 return query; 272 return query;
265 } 273 }