This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new c7e2d8e67c5 Optimize insertRelationalTablet performance (#14197)
c7e2d8e67c5 is described below
commit c7e2d8e67c5efafaf7b16bddb576b998881106cc
Author: Haonan <[email protected]>
AuthorDate: Tue Nov 26 14:31:13 2024 +0800
Optimize insertRelationalTablet performance (#14197)
* Optimize single device insert relation tablet performance
* optimize ttl check
---
.../planner/plan/node/write/InsertTabletNode.java | 12 +--
.../node/write/RelationalInsertTabletNode.java | 88 +++++++++++++++-------
.../plan/relational/planner/RelationPlanner.java | 3 +
.../plan/relational/sql/ast/InsertTablet.java | 3 +
.../plan/statement/crud/InsertTabletStatement.java | 10 +++
.../db/storageengine/dataregion/DataRegion.java | 2 +-
6 files changed, 80 insertions(+), 38 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
index 093f3715957..2773206a9db 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
@@ -70,7 +70,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
-import java.util.function.IntToLongFunction;
import static org.apache.iotdb.db.utils.CommonUtils.isAlive;
@@ -1229,26 +1228,23 @@ public class InsertTabletNode extends InsertNode
implements WALEntryValue {
/**
* @param results insertion result of each row
- * @param rowTTLGetter the ttl associated with each row
+ * @param ttl the ttl
* @return the position of the first alive row
* @throws OutOfTTLException if all rows have expired the TTL
*/
- public int checkTTL(TSStatus[] results, IntToLongFunction rowTTLGetter)
throws OutOfTTLException {
- return checkTTLInternal(results, rowTTLGetter, true);
+ public int checkTTL(TSStatus[] results, long ttl) throws OutOfTTLException {
+ return checkTTLInternal(results, ttl, true);
}
- protected int checkTTLInternal(
- TSStatus[] results, IntToLongFunction rowTTLGetter, boolean
breakOnFirstAlive)
+ protected int checkTTLInternal(TSStatus[] results, long ttl, boolean
breakOnFirstAlive)
throws OutOfTTLException {
/*
* assume that batch has been sorted by client
*/
int loc = 0;
- long ttl = 0;
int firstAliveLoc = -1;
while (loc < getRowCount()) {
- ttl = rowTTLGetter.applyAsLong(loc);
long currTime = getTimes()[loc];
// skip points that do not satisfy TTL
if (!isAlive(currTime, ttl)) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
index e4f7647ccbd..ed88d5cf191 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/RelationalInsertTabletNode.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
+import org.apache.iotdb.commons.utils.TestOnly;
import org.apache.iotdb.db.exception.query.OutOfTTLException;
import org.apache.iotdb.db.queryengine.plan.analyze.IAnalysis;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
@@ -49,27 +50,13 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.function.IntToLongFunction;
public class RelationalInsertTabletNode extends InsertTabletNode {
// deviceId cache for Table-view insertion
private IDeviceID[] deviceIDs;
- public RelationalInsertTabletNode(
- PlanNodeId id,
- PartialPath devicePath,
- boolean isAligned,
- String[] measurements,
- TSDataType[] dataTypes,
- long[] times,
- BitMap[] bitMaps,
- Object[] columns,
- int rowCount,
- TsTableColumnCategory[] columnCategories) {
- super(id, devicePath, isAligned, measurements, dataTypes, times, bitMaps,
columns, rowCount);
- setColumnCategories(columnCategories);
- }
+ private boolean singleDevice;
public RelationalInsertTabletNode(
PlanNodeId id,
@@ -101,8 +88,46 @@ public class RelationalInsertTabletNode extends
InsertTabletNode {
super(id);
}
+ @TestOnly
+ public RelationalInsertTabletNode(
+ PlanNodeId id,
+ PartialPath devicePath,
+ boolean isAligned,
+ String[] measurements,
+ TSDataType[] dataTypes,
+ long[] times,
+ BitMap[] bitMaps,
+ Object[] columns,
+ int rowCount,
+ TsTableColumnCategory[] columnCategories) {
+ super(id, devicePath, isAligned, measurements, dataTypes, times, bitMaps,
columns, rowCount);
+ setColumnCategories(columnCategories);
+ }
+
+ public void setSingleDevice() {
+ this.singleDevice = true;
+ }
+
@Override
public IDeviceID getDeviceID(int rowIdx) {
+ if (singleDevice) {
+ if (deviceIDs == null) {
+ deviceIDs = new IDeviceID[1];
+ }
+ if (deviceIDs[0] == null) {
+ String[] deviceIdSegments = new String[idColumnIndices.size() + 1];
+ deviceIdSegments[0] = this.getTableName();
+ for (int i = 0; i < idColumnIndices.size(); i++) {
+ final Integer columnIndex = idColumnIndices.get(i);
+ Object idSeg = ((Object[]) columns[columnIndex])[0];
+ boolean isNull =
+ bitMaps != null && bitMaps[columnIndex] != null &&
bitMaps[columnIndex].isMarked(0);
+ deviceIdSegments[i + 1] = !isNull && idSeg != null ?
idSeg.toString() : null;
+ }
+ deviceIDs[0] = Factory.DEFAULT_FACTORY.create(deviceIdSegments);
+ }
+ return deviceIDs[0];
+ }
if (deviceIDs == null) {
deviceIDs = new IDeviceID[rowCount];
}
@@ -139,18 +164,23 @@ public class RelationalInsertTabletNode extends
InsertTabletNode {
long[] subTimes = new long[count];
Object[] values = initTabletValues(dataTypes.length, count, dataTypes);
BitMap[] newBitMaps = this.bitMaps == null ? null :
initBitmaps(dataTypes.length, count);
- return new RelationalInsertTabletNode(
- getPlanNodeId(),
- targetPath,
- isAligned,
- measurements,
- dataTypes,
- measurementSchemas,
- subTimes,
- newBitMaps,
- values,
- subTimes.length,
- columnCategories);
+ RelationalInsertTabletNode split =
+ new RelationalInsertTabletNode(
+ getPlanNodeId(),
+ targetPath,
+ isAligned,
+ measurements,
+ dataTypes,
+ measurementSchemas,
+ subTimes,
+ newBitMaps,
+ values,
+ subTimes.length,
+ columnCategories);
+ if (singleDevice) {
+ split.setSingleDevice();
+ }
+ return split;
}
protected Map<TRegionReplicaSet, List<Integer>> splitByReplicaSet(
@@ -303,8 +333,8 @@ public class RelationalInsertTabletNode extends
InsertTabletNode {
}
@Override
- public int checkTTL(TSStatus[] results, IntToLongFunction rowTTLGetter)
throws OutOfTTLException {
- return checkTTLInternal(results, rowTTLGetter, false);
+ public int checkTTL(TSStatus[] results, long ttl) throws OutOfTTLException {
+ return checkTTLInternal(results, ttl, false);
}
@Override
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
index 469c571fe3b..04fa9b2ee49 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/RelationPlanner.java
@@ -654,6 +654,9 @@ public class RelationPlanner extends
AstVisitor<RelationPlan, Void> {
insertTabletStatement.getRowCount(),
insertTabletStatement.getColumnCategories());
insertNode.setFailedMeasurementNumber(insertTabletStatement.getFailedMeasurementNumber());
+ if (insertTabletStatement.isSingleDevice()) {
+ insertNode.setSingleDevice();
+ }
return new RelationPlan(
insertNode, analysis.getRootScope(), Collections.emptyList(),
outerContext);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertTablet.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertTablet.java
index 86de18bf0b9..9894adb4d01 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertTablet.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertTablet.java
@@ -107,5 +107,8 @@ public class InsertTablet extends WrappedInsertStatement {
IDeviceID deviceID = insertTabletStatement.getTableDeviceID(i);
deviceID2LastIdxMap.put(deviceID, i);
}
+ if (deviceID2LastIdxMap.size() == 1) {
+ insertTabletStatement.setSingleDevice();
+ }
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertTabletStatement.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertTabletStatement.java
index fe632bc4978..eec9350ce5e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertTabletStatement.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertTabletStatement.java
@@ -71,6 +71,8 @@ public class InsertTabletStatement extends
InsertBaseStatement implements ISchem
private IDeviceID[] deviceIDs;
+ private boolean singleDevice;
+
protected int rowCount = 0;
/**
@@ -471,6 +473,14 @@ public class InsertTabletStatement extends
InsertBaseStatement implements ISchem
return deviceIDs[rowIdx];
}
+ public void setSingleDevice() {
+ singleDevice = true;
+ }
+
+ public boolean isSingleDevice() {
+ return singleDevice;
+ }
+
@Override
public void insertColumn(int pos, ColumnSchema columnSchema) {
super.insertColumn(pos, columnSchema);
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
index 3b3bb70e329..468f217f7ae 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java
@@ -1237,7 +1237,7 @@ public class DataRegion implements IDataRegionForQuery {
InsertTabletNode insertTabletNode, TSStatus[] results, long[]
infoForMetrics)
throws OutOfTTLException {
boolean noFailure;
- int loc = insertTabletNode.checkTTL(results, i ->
getTTL(insertTabletNode));
+ int loc = insertTabletNode.checkTTL(results, getTTL(insertTabletNode));
noFailure = loc == 0;
List<Pair<IDeviceID, Integer>> deviceEndOffsetPairs =
insertTabletNode.splitByDevice(loc, insertTabletNode.getRowCount());