You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xi...@apache.org on 2021/09/14 07:00:10 UTC

[iotdb] branch master updated: [IOTDB-1666] Implement vector support align by device (#3916)

This is an automated email from the ASF dual-hosted git repository.

xiangweiwei 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 511cb00  [IOTDB-1666] Implement vector support align by device (#3916)
511cb00 is described below

commit 511cb00e948a3dfa9d435daf8ffa4ba9a5d9317f
Author: Xiangwei Wei <34...@users.noreply.github.com>
AuthorDate: Tue Sep 14 14:59:41 2021 +0800

    [IOTDB-1666] Implement vector support align by device (#3916)
---
 .../apache/iotdb/cluster/metadata/CMManager.java   |  41 +----
 .../cluster/query/ClusterDataQueryExecutor.java    |   2 +-
 .../iotdb/cluster/query/ClusterPlanExecutor.java   |  10 --
 .../iotdb/cluster/query/LocalQueryExecutor.java    |   6 +-
 .../query/dataset/ClusterAlignByDeviceDataSet.java |  61 --------
 .../cluster/query/reader/ClusterReaderFactory.java |  12 +-
 .../query/reader/mult/RemoteMultSeriesReader.java  |   3 +-
 .../iotdb/AlignedTimeseriesSessionExample.java     |   6 +-
 .../iotdb/HybridTimeseriesSessionExample.java      |   5 +-
 .../iotdb/tsfile/TsFileWriteVectorWithTablet.java  |   2 +-
 .../db/engine/cache/TimeSeriesMetadataCache.java   | 121 ++++++---------
 .../iotdb/db/engine/memtable/AbstractMemTable.java |  16 +-
 .../db/engine/memtable/PrimitiveMemTable.java      |   3 +-
 .../db/engine/querycontext/ReadOnlyMemChunk.java   |  19 +--
 .../db/engine/storagegroup/TsFileProcessor.java    |  21 +--
 .../org/apache/iotdb/db/metadata/MManager.java     | 172 ++++++++-------------
 .../java/org/apache/iotdb/db/metadata/MTree.java   |  64 ++++----
 .../org/apache/iotdb/db/metadata/PartialPath.java  |  21 +--
 .../iotdb/db/metadata/VectorPartialPath.java       |  68 ++++++--
 .../db/metadata/lastCache/LastCacheManager.java    |  16 +-
 .../iotdb/db/metadata/mnode/MeasurementMNode.java  |   6 +-
 .../iotdb/db/metadata/template/Template.java       |   2 +-
 .../iotdb/db/qp/logical/crud/QueryOperator.java    |  12 +-
 .../iotdb/db/qp/physical/crud/InsertRowPlan.java   |   3 +-
 .../iotdb/db/qp/physical/crud/LastQueryPlan.java   |   2 -
 .../iotdb/db/qp/physical/crud/QueryPlan.java       |   2 +-
 .../db/qp/physical/crud/RawDataQueryPlan.java      |  30 +---
 .../db/query/dataset/AlignByDeviceDataSet.java     |  54 ++++---
 .../dataset/RawQueryDataSetWithoutValueFilter.java |   6 +-
 .../iotdb/db/query/executor/LastQueryExecutor.java |  12 +-
 .../iotdb/db/query/executor/QueryRouter.java       |   7 -
 .../query/expression/unary/TimeSeriesOperand.java  |   2 +-
 .../query/timegenerator/ServerTimeGenerator.java   |   7 -
 .../org/apache/iotdb/db/utils/FileLoaderUtils.java |  34 ++--
 .../java/org/apache/iotdb/db/utils/MemUtils.java   |   2 +-
 .../iotdb/db/writelog/recover/LogReplayer.java     |   4 +-
 .../java/org/apache/iotdb/session/Session.java     |  13 +-
 .../org/apache/iotdb/session/SessionUtils.java     |   4 +-
 .../apache/iotdb/session/IoTDBSessionSimpleIT.java |  12 +-
 .../apache/iotdb/session/IoTDBSessionVectorIT.java |   5 +-
 .../tsfile/write/chunk/ChunkGroupWriterImpl.java   |   2 +-
 .../tsfile/write/chunk/VectorChunkWriterImpl.java  |   8 +-
 .../apache/iotdb/tsfile/write/record/Tablet.java   |  16 +-
 .../tsfile/write/schema/IMeasurementSchema.java    |  14 +-
 .../tsfile/write/schema/MeasurementSchema.java     |  14 +-
 .../write/schema/VectorMeasurementSchema.java      |  96 ++++++------
 .../write/writer/VectorMeasurementSchemaStub.java  |  14 +-
 47 files changed, 455 insertions(+), 597 deletions(-)

diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
index 75ae379..44172df 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
@@ -80,7 +80,6 @@ import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
 import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import org.apache.thrift.TException;
@@ -98,7 +97,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -195,11 +193,12 @@ public class CMManager extends MManager {
       return TSDataType.INT64;
     }
 
+    String measurement = path.getMeasurement();
     if (path instanceof VectorPartialPath) {
-      if (((VectorPartialPath) path).getSubSensorsPathList().size() != 1) {
+      if (((VectorPartialPath) path).getSubSensorsList().size() != 1) {
         return TSDataType.VECTOR;
       } else {
-        path = ((VectorPartialPath) path).getSubSensorsPathList().get(0);
+        measurement = ((VectorPartialPath) path).getSubSensor(0);
       }
     }
 
@@ -208,7 +207,7 @@ public class CMManager extends MManager {
       cacheLock.readLock().lock();
       IMeasurementMNode measurementMNode = mRemoteMetaCache.get(path);
       if (measurementMNode != null) {
-        return measurementMNode.getDataType(path.getMeasurement());
+        return measurementMNode.getDataType(measurement);
       }
     } finally {
       cacheLock.readLock().unlock();
@@ -228,8 +227,8 @@ public class CMManager extends MManager {
             new MeasurementMNode(
                 null, measurementSchema.getMeasurementId(), measurementSchema, null);
         if (measurementSchema instanceof VectorMeasurementSchema) {
-          for (String subSensorId : measurementSchema.getValueMeasurementIdList()) {
-            cacheMeta(new PartialPath(path.getDevice(), subSensorId), measurementMNode, false);
+          for (int i = 0; i < measurementSchema.getSubMeasurementsList().size(); i++) {
+            cacheMeta(((VectorPartialPath) path).getPathWithSubSensor(i), measurementMNode, false);
           }
           cacheMeta(
               new PartialPath(path.getDevice(), measurementSchema.getMeasurementId()),
@@ -247,38 +246,12 @@ public class CMManager extends MManager {
   }
 
   @Override
-  public Pair<List<PartialPath>, Map<String, Integer>> getSeriesSchemas(List<PartialPath> fullPaths)
-      throws MetadataException {
-    Map<IMNode, PartialPath> nodeToPartialPath = new LinkedHashMap<>();
-    Map<IMNode, List<Integer>> nodeToIndex = new LinkedHashMap<>();
-    for (int i = 0; i < fullPaths.size(); i++) {
-      PartialPath path = fullPaths.get(i);
-      IMeasurementMNode node = getMeasurementMNode(path);
-      super.getNodeToPartialPath(node, nodeToPartialPath, nodeToIndex, path, i);
-    }
-    return getPair(fullPaths, nodeToPartialPath, nodeToIndex);
-  }
-
-  @Override
   public IMeasurementSchema getSeriesSchema(PartialPath fullPath) throws MetadataException {
     return super.getSeriesSchema(fullPath, getMeasurementMNode(fullPath));
   }
 
-  /**
-   * Transform the PartialPath to VectorPartialPath if it is a sub sensor of one vector. otherwise,
-   * we don't change it.
-   */
   @Override
-  public PartialPath transformPath(PartialPath partialPath) throws MetadataException {
-    IMeasurementMNode node = getMeasurementMNode(partialPath);
-    if (node.getSchema() instanceof MeasurementSchema) {
-      return partialPath;
-    } else {
-      return toVectorPath(partialPath);
-    }
-  }
-
-  private IMeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
+  protected IMeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
     IMeasurementMNode node = null;
     // try remote cache first
     try {
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
index 0176b72..b12faa3 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterDataQueryExecutor.java
@@ -129,7 +129,7 @@ public class ClusterDataQueryExecutor extends RawDataQueryExecutor {
     for (int i = 0; i < queryPlan.getDeduplicatedPaths().size(); i++) {
       PartialPath partialPath = queryPlan.getDeduplicatedPaths().get(i);
       TSDataType dataType = queryPlan.getDeduplicatedDataTypes().get(i);
-      String fullPath = PartialPath.getExactFullPath(partialPath);
+      String fullPath = partialPath.getExactFullPath();
       AssignPathManagedMergeReader assignPathManagedMergeReader =
           new AssignPathManagedMergeReader(fullPath, dataType);
       for (AbstractMultPointReader multPointReader : multPointReaders) {
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
index 4118802..2dd5043 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.cluster.exception.CheckConsistencyException;
 import org.apache.iotdb.cluster.metadata.CMManager;
 import org.apache.iotdb.cluster.partition.PartitionGroup;
 import org.apache.iotdb.cluster.partition.slot.SlotPartitionTable;
-import org.apache.iotdb.cluster.query.dataset.ClusterAlignByDeviceDataSet;
 import org.apache.iotdb.cluster.query.filter.SlotSgFilter;
 import org.apache.iotdb.cluster.query.manage.QueryCoordinator;
 import org.apache.iotdb.cluster.rpc.thrift.Node;
@@ -45,15 +44,12 @@ import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
-import org.apache.iotdb.db.qp.physical.crud.AlignByDevicePlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
 import org.apache.iotdb.db.qp.physical.sys.LoadConfigurationPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
-import org.apache.iotdb.db.query.dataset.AlignByDeviceDataSet;
-import org.apache.iotdb.db.query.executor.IQueryRouter;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
@@ -611,12 +607,6 @@ public class ClusterPlanExecutor extends PlanExecutor {
   }
 
   @Override
-  protected AlignByDeviceDataSet getAlignByDeviceDataSet(
-      AlignByDevicePlan plan, QueryContext context, IQueryRouter router) {
-    return new ClusterAlignByDeviceDataSet(plan, context, router);
-  }
-
-  @Override
   protected void loadConfiguration(LoadConfigurationPlan plan) throws QueryProcessException {
     switch (plan.getLoadConfigurationPlanType()) {
       case GLOBAL:
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
index 0175ef9..d8b1e96 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/LocalQueryExecutor.java
@@ -307,11 +307,11 @@ public class LocalQueryExecutor {
               try {
                 if (fullPath.contains("$#$")) {
                   String[] array = fullPath.split(":");
-                  List<PartialPath> subSensorsPathList = new ArrayList<>();
+                  List<String> subSensorsList = new ArrayList<>();
                   for (int i = 1; i < array.length; i++) {
-                    subSensorsPathList.add(new PartialPath(array[i]));
+                    subSensorsList.add(array[i]);
                   }
-                  paths.add(new VectorPartialPath(array[0], subSensorsPathList));
+                  paths.add(new VectorPartialPath(array[0], subSensorsList));
                 } else {
                   paths.add(new PartialPath(fullPath));
                 }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/dataset/ClusterAlignByDeviceDataSet.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/dataset/ClusterAlignByDeviceDataSet.java
deleted file mode 100644
index f65c9a9..0000000
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/dataset/ClusterAlignByDeviceDataSet.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.cluster.query.dataset;
-
-import org.apache.iotdb.cluster.metadata.CMManager;
-import org.apache.iotdb.db.conf.IoTDBConstant;
-import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.qp.physical.crud.AlignByDevicePlan;
-import org.apache.iotdb.db.query.context.QueryContext;
-import org.apache.iotdb.db.query.dataset.AlignByDeviceDataSet;
-import org.apache.iotdb.db.query.executor.IQueryRouter;
-import org.apache.iotdb.db.service.IoTDB;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class ClusterAlignByDeviceDataSet extends AlignByDeviceDataSet {
-
-  public ClusterAlignByDeviceDataSet(
-      AlignByDevicePlan alignByDevicePlan, QueryContext context, IQueryRouter queryRouter) {
-    super(alignByDevicePlan, context, queryRouter);
-  }
-
-  @Override
-  protected Set<String> getDeviceMeasurements(PartialPath device) throws IOException {
-    try {
-      List<PartialPath> matchedPaths = ((CMManager) IoTDB.metaManager).getMatchedPaths(device);
-      Set<String> deviceMeasurements = new HashSet<>();
-      for (PartialPath matchedPath : matchedPaths) {
-        deviceMeasurements.add(
-            matchedPath
-                .getFullPath()
-                .substring(
-                    matchedPath.getFullPath().lastIndexOf(IoTDBConstant.PATH_SEPARATOR) + 1));
-      }
-      return deviceMeasurements;
-    } catch (MetadataException e) {
-      throw new IOException(e);
-    }
-  }
-}
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
index f4ed148..d692830 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/ClusterReaderFactory.java
@@ -339,7 +339,7 @@ public class ClusterReaderFactory {
                 dataGroupMember,
                 ascending,
                 null);
-        partialPathPointReaderMap.put(PartialPath.getExactFullPath(partialPath), seriesPointReader);
+        partialPathPointReaderMap.put(partialPath.getExactFullPath(), seriesPointReader);
       }
 
       if (logger.isDebugEnabled()) {
@@ -709,10 +709,12 @@ public class ClusterReaderFactory {
         path -> {
           if (path instanceof VectorPartialPath) {
             StringBuilder builder = new StringBuilder(path.getFullPath());
-            List<PartialPath> pathList = ((VectorPartialPath) path).getSubSensorsPathList();
-            for (PartialPath partialPath : pathList) {
+            List<String> subSensorsList = ((VectorPartialPath) path).getSubSensorsList();
+            for (String subSensor : subSensorsList) {
               builder.append(":");
-              builder.append(partialPath.getFullPath());
+              builder.append(path.getFullPath());
+              builder.append(".");
+              builder.append(subSensor);
             }
             fullPaths.add(builder.toString());
           } else {
@@ -1138,7 +1140,7 @@ public class ClusterReaderFactory {
               ascending,
               null,
               false);
-      partialPathBatchReaderMap.put(PartialPath.getExactFullPath(partialPath), batchReader);
+      partialPathBatchReaderMap.put(partialPath.getExactFullPath(), batchReader);
     }
     return new MultBatchReader(partialPathBatchReaderMap);
   }
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
index a9bbe22..e80fc1e 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/reader/mult/RemoteMultSeriesReader.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.cluster.client.sync.SyncDataClient;
 import org.apache.iotdb.cluster.config.ClusterDescriptor;
 import org.apache.iotdb.cluster.server.RaftServer;
 import org.apache.iotdb.cluster.server.handlers.caller.GenericHandler;
-import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.utils.SerializeUtils;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
@@ -74,7 +73,7 @@ public class RemoteMultSeriesReader extends AbstractMultPointReader {
     this.cachedBatchs = Maps.newHashMap();
     this.pathToDataType = Maps.newHashMap();
     for (int i = 0; i < sourceInfo.getPartialPaths().size(); i++) {
-      String fullPath = PartialPath.getExactFullPath(sourceInfo.getPartialPaths().get(i));
+      String fullPath = sourceInfo.getPartialPaths().get(i).getExactFullPath();
       this.cachedBatchs.put(fullPath, new ConcurrentLinkedQueue<>());
       this.pathToDataType.put(fullPath, sourceInfo.getDataTypes().get(i));
     }
diff --git a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
index 2bbde9a..11520f6 100644
--- a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
@@ -67,7 +67,7 @@ public class AlignedTimeseriesSessionExample {
 
     selectWithAggregationTest();
 
-    // selectWithAlignByDeviceTest();
+    selectWithAlignByDeviceTest();
 
     session.close();
   }
@@ -255,11 +255,11 @@ public class AlignedTimeseriesSessionExample {
       int rowIndex = tablet.rowSize++;
       tablet.addTimestamp(rowIndex, timestamp);
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(0),
+          schemaList.get(0).getSubMeasurementsList().get(0),
           rowIndex,
           new SecureRandom().nextLong());
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(1),
+          schemaList.get(0).getSubMeasurementsList().get(1),
           rowIndex,
           new SecureRandom().nextInt());
 
diff --git a/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java b/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
index 993fcb3..c2a9ed9 100644
--- a/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/HybridTimeseriesSessionExample.java
@@ -86,10 +86,9 @@ public class HybridTimeseriesSessionExample {
     for (long row = minTime; row < maxTime; row++) {
       int rowIndex = tablet.rowSize++;
       tablet.addTimestamp(rowIndex, timestamp);
+      tablet.addValue(schemaList.get(0).getSubMeasurementsList().get(0), rowIndex, row * 10 + 1L);
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(0), rowIndex, row * 10 + 1L);
-      tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(1), rowIndex, (int) (row * 10 + 2));
+          schemaList.get(0).getSubMeasurementsList().get(1), rowIndex, (int) (row * 10 + 2));
 
       if (tablet.rowSize == tablet.getMaxRowNumber()) {
         session.insertTablet(tablet, true);
diff --git a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java
index b8b4a13..5f3e9ba 100644
--- a/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java
+++ b/example/tsfile/src/main/java/org/apache/iotdb/tsfile/TsFileWriteVectorWithTablet.java
@@ -93,7 +93,7 @@ public class TsFileWriteVectorWithTablet {
           for (int i = 0; i < measurementSchemas.size(); i++) {
             IMeasurementSchema measurementSchema = measurementSchemas.get(i);
             if (measurementSchema instanceof VectorMeasurementSchema) {
-              for (String valueName : measurementSchema.getValueMeasurementIdList()) {
+              for (String valueName : measurementSchema.getSubMeasurementsList()) {
                 tablet.addValue(valueName, row, value);
               }
             }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
index e01ccde..0755c37 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/cache/TimeSeriesMetadataCache.java
@@ -43,7 +43,8 @@ import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -181,12 +182,14 @@ public class TimeSeriesMetadataCache {
   }
 
   /**
-   * Support for vector
+   * Support for vector. allSensors > subSensors
    *
    * @param key vector's own fullPath, e.g. root.sg1.d1.vector
-   * @param subSensorList all subSensors of this vector in one query, e.g. [s1, s2, s3]
-   * @param allSensors all sensors of the device in one device, to vector, this should contain both
-   *     vector name and subSensors' name, e.g. [vector, s1, s2, s3]
+   * @param subSensorList all subSensors of this vector in query, e.g. [vector.s1, vector.s2,
+   *     vector.s3]
+   * @param allSensors all sensors belonging to this device that appear in query. For vector, this
+   *     should contain both vector name and subSensors' name, e.g. [vector, vector.s1, vector.s2,
+   *     vector.s3]
    */
   // Suppress synchronize warning
   // Suppress high Cognitive Complexity warning
@@ -240,36 +243,30 @@ public class TimeSeriesMetadataCache {
             allSensors.removeAll(subSensorList);
             return Collections.emptyList();
           }
-          List<TimeseriesMetadata> timeSeriesMetadataList =
-              readTimeseriesMetadataForVector(reader, key, subSensorList, allSensors);
-          Map<TimeSeriesMetadataCacheKey, TimeseriesMetadata> map = new HashMap<>();
-          // put TimeSeriesMetadata of all sensors used in this query into cache
-          timeSeriesMetadataList.forEach(
-              metadata -> {
-                // for root.sg1.d1.vector1.s1, key.device of vector will only return root.sg1.d1
-                // metadata.getMeasurementId() will return s1, the vector1 is saved in
-                // key.measurement
-                // so we should concat them to get the deviceId for root.sg1.d1.vector1.s1
-                TimeSeriesMetadataCacheKey k =
-                    new TimeSeriesMetadataCacheKey(
-                        key.filePath, key.device, metadata.getMeasurementId());
-                lruCache.put(k, metadata);
-                map.put(k, metadata);
-              });
-          // The reason we don't get from cache is in case that
-          // the cache capacity is too small to contains all the sub sensors of this vector
-          getVectorTimeSeriesMetadataListFromMap(key, subSensorList, res, map);
+          res = readTimeseriesMetadataForVector(reader, key, subSensorList, allSensors);
+          Iterator<TimeseriesMetadata> iterator = res.iterator();
+          Set<String> subSensorSet = new HashSet<>(subSensorList);
+          subSensorSet.add(key.measurement);
+          // Note: allSensors > subSensors
+          // Put TimeSeriesMetadata of all sensors used in this query into cache
+          // Remove redundant TimeSeriesMetadata that do not belong to subSensors
+          while (iterator.hasNext()) {
+            TimeseriesMetadata metadata = iterator.next();
+            TimeSeriesMetadataCacheKey k =
+                new TimeSeriesMetadataCacheKey(
+                    key.filePath, key.device, metadata.getMeasurementId());
+            lruCache.put(k, metadata);
+            if (!subSensorSet.contains(metadata.getMeasurementId())) {
+              iterator.remove();
+            }
+          }
         }
       }
     }
-    if (res.isEmpty()) {
-      if (debug) {
+    if (debug) {
+      if (res.isEmpty()) {
         DEBUG_LOGGER.info("The file doesn't have this time series {}.", key);
-      }
-      allSensors.removeAll(subSensorList);
-      return Collections.emptyList();
-    } else {
-      if (debug) {
+      } else {
         DEBUG_LOGGER.info(
             "Get timeseries: {}.{}  metadata in file: {}  from cache: {}.",
             key.device,
@@ -277,21 +274,20 @@ public class TimeSeriesMetadataCache {
             key.filePath,
             res);
       }
-      for (int i = 0; i < res.size(); i++) {
-        res.set(i, new TimeseriesMetadata(res.get(i)));
-      }
-      allSensors.removeAll(subSensorList);
-      return res;
     }
+
+    allSensors.removeAll(subSensorList);
+    return res;
   }
 
   /**
    * Support for vector, extraction of common function of `get`
    *
    * @param key vector's own fullPath, e.g. root.sg1.d1.vector
-   * @param subSensorList all subSensors of this vector in one query, e.g. [s1, s2, s3]
+   * @param subSensorList all subSensors of this vector in one query, e.g. [vector.s1, vector.s2,
+   *     vector.s3]
    * @param allSensors all sensors of the device in one device, to vector, this should contain both
-   *     vector name and subSensors' name, e.g. [vector, s1, s2, s3]
+   *     vector name and subSensors' name, e.g. [vector, vector.s1, vector.s2, vector.s3]
    * @param reader TsFileSequenceReader created by file
    */
   private List<TimeseriesMetadata> readTimeseriesMetadataForVector(
@@ -320,16 +316,15 @@ public class TimeSeriesMetadataCache {
       }
     }
     while (!subSensorsSet.isEmpty()) {
-      Path subPath =
-          new Path(
-              key.device, key.measurement + TsFileConstant.PATH_SEPARATOR + subSensorsSet.first());
-      List<TimeseriesMetadata> subList = reader.readTimeseriesMetadata(subPath, allSensors);
-      for (TimeseriesMetadata tsMetadata : subList) {
+      Path subPath = new Path(key.device, subSensorsSet.first());
+      List<TimeseriesMetadata> subTsMetaDataList =
+          reader.readTimeseriesMetadata(subPath, allSensors);
+      for (TimeseriesMetadata tsMetadata : subTsMetaDataList) {
         if (!subSensorsSet.isEmpty() && subSensorsSet.contains(tsMetadata.getMeasurementId())) {
           subSensorsSet.remove(tsMetadata.getMeasurementId());
         }
       }
-      timeSeriesMetadataList.addAll(subList);
+      timeSeriesMetadataList.addAll(subTsMetaDataList);
     }
     return timeSeriesMetadataList;
   }
@@ -338,41 +333,11 @@ public class TimeSeriesMetadataCache {
    * !!!Attention!!!
    *
    * <p>For a vector, e.g. root.sg1.d1.vector1(s1, s2) TimeSeriesMetadataCacheKey for vector1 should
-   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1.vector1, measurement: vector1},
-   * vector1 will be in both device and measurement TimeSeriesMetadataCacheKey for vector1.s1 should
-   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1.vector1, measurement: s1}
-   * TimeSeriesMetadataCacheKey for vector1.s2 should be {filePath: ""./data/data/seq/.......,
-   * device: root.sg1.d1.vector1, measurement: s2}
-   */
-  private void getVectorTimeSeriesMetadataListFromMap(
-      TimeSeriesMetadataCacheKey key,
-      List<String> subSensorList,
-      List<TimeseriesMetadata> res,
-      Map<TimeSeriesMetadataCacheKey, TimeseriesMetadata> map) {
-    TimeseriesMetadata timeseriesMetadata = map.get(key);
-    if (timeseriesMetadata != null) {
-      res.add(timeseriesMetadata);
-      for (String subSensor : subSensorList) {
-        timeseriesMetadata =
-            map.get(new TimeSeriesMetadataCacheKey(key.filePath, key.device, subSensor));
-        if (timeseriesMetadata != null) {
-          res.add(timeseriesMetadata);
-        } else {
-          break;
-        }
-      }
-    }
-  }
-
-  /**
-   * !!!Attention!!!
-   *
-   * <p>For a vector, e.g. root.sg1.d1.vector1(s1, s2) TimeSeriesMetadataCacheKey for vector1 should
-   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1.vector1, measurement: vector1},
-   * vector1 will be in both device and measurement TimeSeriesMetadataCacheKey for vector1.s1 should
-   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1.vector1, measurement: s1}
+   * be {filePath: ""./data/data/seq/......., device: root.sg1.d1, measurement: vector1}, vector1
+   * will be in both device and measurement TimeSeriesMetadataCacheKey for vector1.s1 should be
+   * {filePath: ""./data/data/seq/......., device: root.sg1.d1, measurement: vector.s1}
    * TimeSeriesMetadataCacheKey for vector1.s2 should be {filePath: ""./data/data/seq/.......,
-   * device: root.sg1.d1.vector1, measurement: s2}
+   * device: root.sg1.d1, measurement: vector.s2}
    */
   private void getVectorTimeSeriesMetadataListFromCache(
       TimeSeriesMetadataCacheKey key, List<String> subSensorList, List<TimeseriesMetadata> res) {
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index 984ce32..fed4851 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -131,14 +131,14 @@ public abstract class AbstractMemTable implements IMemTable {
       if (measurementMNode != null) {
         // write vector
         Object[] vectorValue =
-            new Object[measurementMNode.getSchema().getValueTSDataTypeList().size()];
+            new Object[measurementMNode.getSchema().getSubMeasurementsTSDataTypeList().size()];
         for (int j = 0; j < vectorValue.length; j++) {
           vectorValue[j] = values[columnIndex];
           columnIndex++;
         }
         memSize +=
             MemUtils.getVectorRecordSize(
-                measurementMNode.getSchema().getValueTSDataTypeList(),
+                measurementMNode.getSchema().getSubMeasurementsTSDataTypeList(),
                 vectorValue,
                 disableMemControl);
         write(
@@ -209,9 +209,9 @@ public abstract class AbstractMemTable implements IMemTable {
       if (insertTabletPlan.isAligned()) {
         VectorMeasurementSchema vectorSchema =
             (VectorMeasurementSchema) insertTabletPlan.getMeasurementMNodes()[i].getSchema();
-        Object[] columns = new Object[vectorSchema.getValueMeasurementIdList().size()];
-        BitMap[] bitMaps = new BitMap[vectorSchema.getValueMeasurementIdList().size()];
-        for (int j = 0; j < vectorSchema.getValueMeasurementIdList().size(); j++) {
+        Object[] columns = new Object[vectorSchema.getSubMeasurementsList().size()];
+        BitMap[] bitMaps = new BitMap[vectorSchema.getSubMeasurementsList().size()];
+        for (int j = 0; j < vectorSchema.getSubMeasurementsList().size(); j++) {
           columns[j] = insertTabletPlan.getColumns()[columnIndex];
           if (insertTabletPlan.getBitMaps() != null) {
             bitMaps[j] = insertTabletPlan.getBitMaps()[columnIndex];
@@ -321,11 +321,11 @@ public abstract class AbstractMemTable implements IMemTable {
         return null;
       }
 
-      List<String> measurementIdList = partialVectorSchema.getValueMeasurementIdList();
+      List<String> measurementIdList = partialVectorSchema.getSubMeasurementsList();
       List<Integer> columns = new ArrayList<>();
       IMeasurementSchema vectorSchema = vectorMemChunk.getSchema();
       for (String queryingMeasurement : measurementIdList) {
-        columns.add(vectorSchema.getValueMeasurementIdList().indexOf(queryingMeasurement));
+        columns.add(vectorSchema.getSubMeasurementsList().indexOf(queryingMeasurement));
       }
       // get sorted tv list is synchronized so different query can get right sorted list reference
       TVList vectorTvListCopy = vectorMemChunk.getSortedTvListForQuery(columns);
@@ -376,7 +376,7 @@ public abstract class AbstractMemTable implements IMemTable {
       // for vector type
       else if (schema.getType() == TSDataType.VECTOR) {
         List<String> measurements = MetaUtils.getMeasurementsInPartialPath(originalPath);
-        if (measurements.containsAll(schema.getValueMeasurementIdList())) {
+        if (measurements.containsAll(schema.getSubMeasurementsList())) {
           if (startTimestamp == Long.MIN_VALUE && endTimestamp == Long.MAX_VALUE) {
             iter.remove();
           }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
index e13bbf2..922cb12 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTable.java
@@ -42,7 +42,8 @@ public class PrimitiveMemTable extends AbstractMemTable {
   protected IWritableMemChunk genMemSeries(IMeasurementSchema schema) {
     if (schema.getType() == TSDataType.VECTOR) {
       return new WritableMemChunk(
-          schema, TVListAllocator.getInstance().allocate(schema.getValueTSDataTypeList()));
+          schema,
+          TVListAllocator.getInstance().allocate(schema.getSubMeasurementsTSDataTypeList()));
     }
     return new WritableMemChunk(schema, TVListAllocator.getInstance().allocate(schema.getType()));
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
index e7e83db..bdd9e3b 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/querycontext/ReadOnlyMemChunk.java
@@ -173,13 +173,14 @@ public class ReadOnlyMemChunk {
     IChunkMetadata timeChunkMetadata =
         new ChunkMetadata(measurementUid, TSDataType.VECTOR, 0, timeStatistics);
     List<IChunkMetadata> valueChunkMetadataList = new ArrayList<>();
-    Statistics[] valueStatistics = new Statistics[schema.getValueTSDataTypeList().size()];
-    for (int i = 0; i < schema.getValueTSDataTypeList().size(); i++) {
-      valueStatistics[i] = Statistics.getStatsByType(schema.getValueTSDataTypeList().get(i));
+    Statistics[] valueStatistics = new Statistics[schema.getSubMeasurementsTSDataTypeList().size()];
+    for (int i = 0; i < schema.getSubMeasurementsTSDataTypeList().size(); i++) {
+      valueStatistics[i] =
+          Statistics.getStatsByType(schema.getSubMeasurementsTSDataTypeList().get(i));
       IChunkMetadata valueChunkMetadata =
           new ChunkMetadata(
-              schema.getValueMeasurementIdList().get(i),
-              schema.getValueTSDataTypeList().get(i),
+              schema.getSubMeasurementsList().get(i),
+              schema.getSubMeasurementsTSDataTypeList().get(i),
               0,
               valueStatistics[i]);
       valueChunkMetadataList.add(valueChunkMetadata);
@@ -190,7 +191,7 @@ public class ReadOnlyMemChunk {
       while (iterator.hasNextTimeValuePair()) {
         TimeValuePair timeValuePair = iterator.nextTimeValuePair();
         timeStatistics.update(timeValuePair.getTimestamp());
-        if (schema.getValueTSDataTypeList().size() == 1) {
+        if (schema.getSubMeasurementsTSDataTypeList().size() == 1) {
           updateValueStatisticsForSingleColumn(schema, valueStatistics, timeValuePair);
         } else {
           updateValueStatistics(schema, valueStatistics, timeValuePair);
@@ -212,7 +213,7 @@ public class ReadOnlyMemChunk {
   private void updateValueStatisticsForSingleColumn(
       IMeasurementSchema schema, Statistics[] valueStatistics, TimeValuePair timeValuePair)
       throws QueryProcessException {
-    switch (schema.getValueTSDataTypeList().get(0)) {
+    switch (schema.getSubMeasurementsTSDataTypeList().get(0)) {
       case BOOLEAN:
         valueStatistics[0].update(
             timeValuePair.getTimestamp(), timeValuePair.getValue().getBoolean());
@@ -243,11 +244,11 @@ public class ReadOnlyMemChunk {
   private void updateValueStatistics(
       IMeasurementSchema schema, Statistics[] valueStatistics, TimeValuePair timeValuePair)
       throws QueryProcessException {
-    for (int i = 0; i < schema.getValueTSDataTypeList().size(); i++) {
+    for (int i = 0; i < schema.getSubMeasurementsTSDataTypeList().size(); i++) {
       if (timeValuePair.getValue().getVector()[i] == null) {
         continue;
       }
-      switch (schema.getValueTSDataTypeList().get(i)) {
+      switch (schema.getSubMeasurementsTSDataTypeList().get(i)) {
         case BOOLEAN:
           valueStatistics[i].update(
               timeValuePair.getTimestamp(), timeValuePair.getValue().getVector()[i].getBoolean());
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index 7745138..f6a9270 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -341,11 +341,12 @@ public class TsFileProcessor {
         IMeasurementSchema schema = insertRowPlan.getMeasurementMNodes()[i].getSchema();
         if (schema.getType() == TSDataType.VECTOR) {
           chunkMetadataIncrement +=
-              schema.getValueTSDataTypeList().size()
+              schema.getSubMeasurementsTSDataTypeList().size()
                   * ChunkMetadata.calculateRamSize(
-                      schema.getValueMeasurementIdList().get(0),
-                      schema.getValueTSDataTypeList().get(0));
-          memTableIncrement += TVList.vectorTvListArrayMemSize(schema.getValueTSDataTypeList());
+                      schema.getSubMeasurementsList().get(0),
+                      schema.getSubMeasurementsTSDataTypeList().get(0));
+          memTableIncrement +=
+              TVList.vectorTvListArrayMemSize(schema.getSubMeasurementsTSDataTypeList());
         } else {
           chunkMetadataIncrement +=
               ChunkMetadata.calculateRamSize(
@@ -386,8 +387,8 @@ public class TsFileProcessor {
       if (insertTabletPlan.isAligned()) {
         VectorMeasurementSchema vectorSchema =
             (VectorMeasurementSchema) insertTabletPlan.getMeasurementMNodes()[i].getSchema();
-        Object[] columns = new Object[vectorSchema.getValueMeasurementIdList().size()];
-        for (int j = 0; j < vectorSchema.getValueMeasurementIdList().size(); j++) {
+        Object[] columns = new Object[vectorSchema.getSubMeasurementsList().size()];
+        for (int j = 0; j < vectorSchema.getSubMeasurementsList().size(); j++) {
           columns[j] = insertTabletPlan.getColumns()[columnIndex++];
         }
         updateVectorMemCost(vectorSchema, deviceId, start, end, memIncrements, columns);
@@ -459,8 +460,8 @@ public class TsFileProcessor {
       Object[] columns) {
     // memIncrements = [memTable, text, chunk metadata] respectively
 
-    List<String> measurementIds = vectorSchema.getValueMeasurementIdList();
-    List<TSDataType> dataTypes = vectorSchema.getValueTSDataTypeList();
+    List<String> measurementIds = vectorSchema.getSubMeasurementsList();
+    List<TSDataType> dataTypes = vectorSchema.getSubMeasurementsTSDataTypeList();
     if (workMemTable.checkIfChunkDoesNotExist(deviceId, vectorSchema.getMeasurementId())) {
       // ChunkMetadataIncrement
       memIncrements[2] +=
@@ -1252,8 +1253,8 @@ public class TsFileProcessor {
         List<ChunkMetadata> timeChunkMetadataList =
             writer.getVisibleMetadataList(deviceId, measurementId, schema.getType());
         List<List<ChunkMetadata>> valueChunkMetadataList = new ArrayList<>();
-        List<String> valueMeasurementIdList = schema.getValueMeasurementIdList();
-        List<TSDataType> valueDataTypeList = schema.getValueTSDataTypeList();
+        List<String> valueMeasurementIdList = schema.getSubMeasurementsList();
+        List<TSDataType> valueDataTypeList = schema.getSubMeasurementsTSDataTypeList();
         for (int i = 0; i < valueMeasurementIdList.size(); i++) {
           valueChunkMetadataList.add(
               writer.getVisibleMetadataList(
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index 5ea0477..e2205ce 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -23,11 +23,24 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
 import org.apache.iotdb.db.engine.trigger.executor.TriggerEngine;
-import org.apache.iotdb.db.exception.metadata.*;
+import org.apache.iotdb.db.exception.metadata.AliasAlreadyExistException;
+import org.apache.iotdb.db.exception.metadata.AlignedTimeseriesException;
+import org.apache.iotdb.db.exception.metadata.DataTypeMismatchException;
+import org.apache.iotdb.db.exception.metadata.DeleteFailedException;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
+import org.apache.iotdb.db.exception.metadata.PathNotExistException;
+import org.apache.iotdb.db.exception.metadata.StorageGroupAlreadySetException;
+import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.lastCache.LastCacheManager;
 import org.apache.iotdb.db.metadata.logfile.MLogReader;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
-import org.apache.iotdb.db.metadata.mnode.*;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.metadata.tag.TagManager;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
@@ -591,10 +604,11 @@ public class MManager {
       if (lastNode.isMeasurement()) {
         IMeasurementSchema schema = ((IMeasurementMNode) lastNode).getSchema();
         if (schema instanceof VectorMeasurementSchema) {
-          if (schema.getValueMeasurementIdList().size() != allTimeseries.size()) {
+          if (schema.getSubMeasurementsList().size() != allTimeseries.size()) {
             throw new AlignedTimeseriesException(
                 "Not support deleting part of aligned timeseies!", prefixPath.getFullPath());
           } else {
+            allTimeseries.clear();
             allTimeseries.add(lastNode.getPartialPath());
           }
         }
@@ -653,7 +667,7 @@ public class MManager {
       removeFromTagInvertedIndex(pair.right);
       timeseriesNum = 1;
     } else if (schema instanceof VectorMeasurementSchema) {
-      timeseriesNum += schema.getValueTSDataTypeList().size();
+      timeseriesNum += schema.getSubMeasurementsTSDataTypeList().size();
     }
     PartialPath storageGroupPath = pair.left;
 
@@ -750,19 +764,17 @@ public class MManager {
       return TSDataType.INT64;
     }
 
-    if (path instanceof VectorPartialPath) {
-      if (((VectorPartialPath) path).getSubSensorsPathList().size() != 1) {
-        return TSDataType.VECTOR;
-      } else {
-        path = ((VectorPartialPath) path).getSubSensorsPathList().get(0);
-      }
-    }
     IMeasurementSchema schema = mtree.getSchema(path);
     if (schema instanceof MeasurementSchema) {
       return schema.getType();
     } else {
-      List<String> measurements = schema.getValueMeasurementIdList();
-      return schema.getValueTSDataTypeList().get(measurements.indexOf(path.getMeasurement()));
+      if (((VectorPartialPath) path).getSubSensorsList().size() != 1) {
+        return TSDataType.VECTOR;
+      } else {
+        String subSensor = ((VectorPartialPath) path).getSubSensor(0);
+        List<String> measurements = schema.getSubMeasurementsList();
+        return schema.getSubMeasurementsTSDataTypeList().get(measurements.indexOf(subSensor));
+      }
     }
   }
 
@@ -989,7 +1001,7 @@ public class MManager {
         }
         res.add(
             new ShowTimeSeriesResult(
-                ansString.left.getFullPath(),
+                ansString.left.getExactFullPath(),
                 ansString.right[0],
                 ansString.right[1],
                 TSDataType.valueOf(ansString.right[2]),
@@ -1039,53 +1051,37 @@ public class MManager {
   protected IMeasurementSchema getSeriesSchema(PartialPath fullPath, IMeasurementMNode leaf) {
     IMeasurementSchema schema = leaf.getSchema();
 
-    if (schema == null || schema.getType() != TSDataType.VECTOR) {
+    if (!(fullPath instanceof VectorPartialPath)
+        || schema == null
+        || schema.getType() != TSDataType.VECTOR) {
       return schema;
     }
-    List<String> measurementsInLeaf = schema.getValueMeasurementIdList();
-    List<PartialPath> measurements = ((VectorPartialPath) fullPath).getSubSensorsPathList();
-    TSDataType[] types = new TSDataType[measurements.size()];
-    TSEncoding[] encodings = new TSEncoding[measurements.size()];
+    List<String> measurementsInLeaf = schema.getSubMeasurementsList();
+    List<String> subMeasurements = ((VectorPartialPath) fullPath).getSubSensorsList();
+    TSDataType[] types = new TSDataType[subMeasurements.size()];
+    TSEncoding[] encodings = new TSEncoding[subMeasurements.size()];
 
-    for (int i = 0; i < measurements.size(); i++) {
-      int index = measurementsInLeaf.indexOf(measurements.get(i).getMeasurement());
-      types[i] = schema.getValueTSDataTypeList().get(index);
-      encodings[i] = schema.getValueTSEncodingList().get(index);
+    for (int i = 0; i < subMeasurements.size(); i++) {
+      int index = measurementsInLeaf.indexOf(subMeasurements.get(i));
+      types[i] = schema.getSubMeasurementsTSDataTypeList().get(index);
+      encodings[i] = schema.getSubMeasurementsTSEncodingList().get(index);
     }
-    String[] array = new String[measurements.size()];
+    String[] array = new String[subMeasurements.size()];
     for (int i = 0; i < array.length; i++) {
-      array[i] = measurements.get(i).getMeasurement();
+      array[i] = subMeasurements.get(i);
     }
     return new VectorMeasurementSchema(
         schema.getMeasurementId(), array, types, encodings, schema.getCompressor());
   }
 
   /**
-   * Transform the PartialPath to VectorPartialPath if it is a sub sensor of one vector. otherwise,
-   * we don't change it.
-   */
-  public PartialPath transformPath(PartialPath partialPath) throws MetadataException {
-    IMeasurementMNode node = (IMeasurementMNode) getNodeByPath(partialPath);
-    if (node.getSchema() instanceof MeasurementSchema) {
-      return partialPath;
-    } else {
-      return toVectorPath(partialPath);
-    }
-  }
-
-  /** Convert the PartialPath to VectorPartialPath. */
-  protected VectorPartialPath toVectorPath(PartialPath partialPath) throws MetadataException {
-    List<PartialPath> subSensorsPathList = new ArrayList<>();
-    subSensorsPathList.add(partialPath);
-    return new VectorPartialPath(partialPath.getDevice(), subSensorsPathList);
-  }
-
-  /**
-   * Get schema of partialPaths, in which aligned timeseries should only organized to one schema.
-   * This method should be called when logical plan converts to physical plan.
+   * Get schema of partialPaths, in which aligned time series should only organized to one schema.
+   * BEFORE this method, all the aligned time series is NOT united. For example,
+   * VectorMeasurementSchema(root.sg.d1.vector1 [s1,s2]) will be * root.sg.d1.vector1[s1],
+   * root.sg.d1.vector1[s2]
    *
-   * @param fullPaths full path list without pointing out which timeseries are aligned. For example,
-   *     maybe (s1,s2) are aligned, but the input could be [root.sg1.d1.s1, root.sg1.d1.s2]
+   * @param fullPaths full path list without uniting the sub measurement under the same aligned time
+   *     series.
    * @return Size of partial path list could NOT equal to the input list size. For example, the
    *     VectorMeasurementSchema (s1,s2) would be returned once; Size of integer list must equal to
    *     the input list size. It indicates the index of elements of original list in the result list
@@ -1093,68 +1089,28 @@ public class MManager {
   public Pair<List<PartialPath>, Map<String, Integer>> getSeriesSchemas(List<PartialPath> fullPaths)
       throws MetadataException {
     Map<IMNode, PartialPath> nodeToPartialPath = new LinkedHashMap<>();
-    Map<IMNode, List<Integer>> nodeToIndex = new LinkedHashMap<>();
+    Map<String, Integer> pathIndex = new LinkedHashMap<>();
     for (int i = 0; i < fullPaths.size(); i++) {
       PartialPath path = fullPaths.get(i);
-      // use dfs to collect paths
-      IMeasurementMNode node = (IMeasurementMNode) getNodeByPath(path);
-      getNodeToPartialPath(node, nodeToPartialPath, nodeToIndex, path, i);
-    }
-    return getPair(fullPaths, nodeToPartialPath, nodeToIndex);
-  }
-
-  protected void getNodeToPartialPath(
-      IMeasurementMNode node,
-      Map<IMNode, PartialPath> nodeToPartialPath,
-      Map<IMNode, List<Integer>> nodeToIndex,
-      PartialPath path,
-      int index)
-      throws MetadataException {
-    if (!nodeToPartialPath.containsKey(node)) {
-      if (node.getSchema() instanceof MeasurementSchema) {
-        nodeToPartialPath.put(node, path);
-      } else {
-        List<PartialPath> subSensorsPathList = new ArrayList<>();
-        subSensorsPathList.add(path);
-        nodeToPartialPath.put(node, new VectorPartialPath(node.getFullPath(), subSensorsPathList));
-      }
-      nodeToIndex.computeIfAbsent(node, k -> new ArrayList<>()).add(index);
-    } else {
-      // if nodeToPartialPath contains node
-      String existPath = nodeToPartialPath.get(node).getFullPath();
-      if (existPath.equals(path.getFullPath())) {
-        // could be the same path in different aggregate functions
-        nodeToIndex.get(node).add(index);
-      } else {
-        // could be VectorPartialPath
-        ((VectorPartialPath) nodeToPartialPath.get(node)).addSubSensor(path);
-        nodeToIndex.get(node).add(index);
+      pathIndex.put(path.getExactFullPath(), i);
+      if (path.isMeasurementAliasExists()) {
+        pathIndex.put(path.getFullPathWithAlias(), i);
       }
-    }
-  }
 
-  protected Pair<List<PartialPath>, Map<String, Integer>> getPair(
-      List<PartialPath> fullPaths,
-      Map<IMNode, PartialPath> nodeToPartialPath,
-      Map<IMNode, List<Integer>> nodeToIndex)
-      throws MetadataException {
-    Map<String, Integer> indexMap = new HashMap<>();
-    int i = 0;
-    for (List<Integer> indexList : nodeToIndex.values()) {
-      for (int index : indexList) {
-        PartialPath partialPath = fullPaths.get(i);
-        if (indexMap.containsKey(partialPath.getFullPath())) {
-          throw new MetadataException(
-              "Query for measurement and its alias at the same time!", true);
-        }
-        indexMap.put(partialPath.getFullPath(), index);
-        if (partialPath.isMeasurementAliasExists()) {
-          indexMap.put(partialPath.getFullPathWithAlias(), index);
+      IMeasurementMNode node = getMeasurementMNode(path);
+      if (!nodeToPartialPath.containsKey(node)) {
+        nodeToPartialPath.put(node, path.copy());
+      } else {
+        // if nodeToPartialPath contains node
+        PartialPath existPath = nodeToPartialPath.get(node);
+        if (!existPath.equals(path)) {
+          // could be VectorPartialPath
+          ((VectorPartialPath) existPath)
+              .addSubSensor(((VectorPartialPath) path).getSubSensorsList());
         }
-        i++;
       }
     }
-    return new Pair<>(new ArrayList<>(nodeToPartialPath.values()), indexMap);
+    return new Pair<>(new ArrayList<>(nodeToPartialPath.values()), pathIndex);
   }
 
   /**
@@ -1191,6 +1147,10 @@ public class MManager {
     return mtree.isPathExist(path);
   }
 
+  protected IMeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
+    return (IMeasurementMNode) getNodeByPath(fullPath);
+  }
+
   /** Get node by path */
   public IMNode getNodeByPath(PartialPath path) throws MetadataException {
     return mtree.getNodeByPath(path);
@@ -1937,7 +1897,7 @@ public class MManager {
         if (plan instanceof InsertRowPlan || plan instanceof InsertTabletPlan) {
           if (plan.isAligned()) {
             TSDataType dataTypeInNode =
-                measurementMNode.getSchema().getValueTSDataTypeList().get(i);
+                measurementMNode.getSchema().getSubMeasurementsTSDataTypeList().get(i);
             insertDataType = plan.getDataTypes()[i];
             if (insertDataType == null) {
               insertDataType = dataTypeInNode;
@@ -1945,7 +1905,7 @@ public class MManager {
             if (dataTypeInNode != insertDataType) {
               logger.warn(
                   "DataType mismatch, Insert measurement {} in {} type {}, metadata tree type {}",
-                  measurementMNode.getSchema().getValueMeasurementIdList().get(i),
+                  measurementMNode.getSchema().getSubMeasurementsList().get(i),
                   measurementList[i],
                   insertDataType,
                   dataTypeInNode);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index e6d69f4..5852108 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -446,7 +446,7 @@ public class MTree implements Serializable {
         }
         if (((IMeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
           return i == nodeNames.length - 2
-              && ((IMeasurementMNode) cur).getSchema().isCompatible(nodeNames[i + 1]);
+              && ((IMeasurementMNode) cur).getSchema().containsSubMeasurement(nodeNames[i + 1]);
         } else {
           return false;
         }
@@ -999,7 +999,7 @@ public class MTree implements Serializable {
       throws PathNotExistException {
     if (node.isMeasurement()) {
       if (idx < nodes.length) {
-        if (((IMeasurementMNode) node).getSchema().isCompatible(nodes[idx])) {
+        if (((IMeasurementMNode) node).getSchema().containsSubMeasurement(nodes[idx])) {
           return 1;
         } else {
           if (!wildcard) {
@@ -1229,36 +1229,36 @@ public class MTree implements Serializable {
    */
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
   private void findPath(
-      IMNode node,
+      IMNode curNode,
       String[] nodes,
-      int idx,
+      int childIndex,
       List<Pair<PartialPath, String[]>> timeseriesSchemaList,
       boolean hasLimit,
       boolean needLast,
       QueryContext queryContext,
       Template upperTemplate)
       throws MetadataException {
-    if (node.isMeasurement()) {
-      if ((nodes.length <= idx
-          || ((IMeasurementMNode) node).getSchema() instanceof VectorMeasurementSchema)) {
+    if (curNode.isMeasurement()) {
+      if ((nodes.length <= childIndex
+          || ((IMeasurementMNode) curNode).getSchema() instanceof VectorMeasurementSchema)) {
         if (hasLimit) {
           curOffset.set(curOffset.get() + 1);
           if (curOffset.get() < offset.get() || count.get().intValue() == limit.get().intValue()) {
             return;
           }
         }
-        IMeasurementSchema measurementSchema = ((IMeasurementMNode) node).getSchema();
+        IMeasurementSchema measurementSchema = ((IMeasurementMNode) curNode).getSchema();
         if (measurementSchema instanceof MeasurementSchema) {
           addMeasurementSchema(
-              node, timeseriesSchemaList, needLast, queryContext, measurementSchema, "*");
+              curNode, timeseriesSchemaList, needLast, queryContext, measurementSchema, "*");
         } else if (measurementSchema instanceof VectorMeasurementSchema) {
           addVectorMeasurementSchema(
-              node,
+              curNode,
               timeseriesSchemaList,
               needLast,
               queryContext,
               measurementSchema,
-              idx < nodes.length ? nodes[idx] : "*");
+              childIndex < nodes.length ? nodes[childIndex] : "*");
         }
         if (hasLimit) {
           count.set(count.get() + 1);
@@ -1267,19 +1267,19 @@ public class MTree implements Serializable {
       return;
     }
 
-    String nodeReg = MetaUtils.getNodeRegByIdx(idx, nodes);
-    if (node.getSchemaTemplate() != null) {
-      upperTemplate = node.getSchemaTemplate();
+    String nodeReg = MetaUtils.getNodeRegByIdx(childIndex, nodes);
+    if (curNode.getSchemaTemplate() != null) {
+      upperTemplate = curNode.getSchemaTemplate();
     }
 
-    // we should use template when all child is measurement or this node has no child
+    // we should use template when all child is measurement or this curNode has no child
     if (!nodeReg.contains(PATH_WILDCARD)) {
-      IMNode next = node.getChild(nodeReg);
+      IMNode next = curNode.getChild(nodeReg);
       if (next != null) {
         findPath(
             next,
             nodes,
-            idx + 1,
+            childIndex + 1,
             timeseriesSchemaList,
             hasLimit,
             needLast,
@@ -1287,14 +1287,14 @@ public class MTree implements Serializable {
             upperTemplate);
       }
     } else {
-      for (IMNode child : node.getChildren().values()) {
+      for (IMNode child : curNode.getChildren().values()) {
         if (!Pattern.matches(nodeReg.replace("*", ".*"), child.getName())) {
           continue;
         }
         findPath(
             child,
             nodes,
-            idx + 1,
+            childIndex + 1,
             timeseriesSchemaList,
             hasLimit,
             needLast,
@@ -1307,14 +1307,14 @@ public class MTree implements Serializable {
     }
 
     // template part
-    if (node.isUseTemplate()) {
+    if (curNode.isUseTemplate()) {
       if (upperTemplate != null) {
         HashSet<IMeasurementSchema> set = new HashSet<>();
         for (IMeasurementSchema schema : upperTemplate.getSchemaMap().values()) {
           if (set.add(schema)) {
             if (schema instanceof MeasurementSchema) {
               addMeasurementSchema(
-                  new MeasurementMNode(node, schema.getMeasurementId(), schema, null),
+                  new MeasurementMNode(curNode, schema.getMeasurementId(), schema, null),
                   timeseriesSchemaList,
                   needLast,
                   queryContext,
@@ -1324,14 +1324,14 @@ public class MTree implements Serializable {
               VectorMeasurementSchema vectorMeasurementSchema = (VectorMeasurementSchema) schema;
               if (Pattern.matches(
                   nodeReg.replace("*", ".*"), vectorMeasurementSchema.getMeasurementId())) {
-                String firstNode = schema.getValueMeasurementIdList().get(0);
+                String firstNode = schema.getSubMeasurementsList().get(0);
                 addVectorMeasurementSchemaForTemplate(
-                    new MeasurementMNode(node, firstNode, schema, null),
+                    new MeasurementMNode(curNode, firstNode, schema, null),
                     timeseriesSchemaList,
                     needLast,
                     queryContext,
                     schema,
-                    MetaUtils.getNodeRegByIdx(idx + 1, nodes),
+                    MetaUtils.getNodeRegByIdx(childIndex + 1, nodes),
                     vectorMeasurementSchema.getMeasurementId());
               }
             }
@@ -1376,7 +1376,7 @@ public class MTree implements Serializable {
       IMeasurementSchema schema,
       String reg)
       throws StorageGroupNotSetException, IllegalPathException {
-    List<String> measurements = schema.getValueMeasurementIdList();
+    List<String> measurements = schema.getSubMeasurementsList();
     for (int i = 0; i < measurements.size(); i++) {
       if (!Pattern.matches(reg.replace("*", ".*"), measurements.get(i))) {
         continue;
@@ -1385,8 +1385,8 @@ public class MTree implements Serializable {
       String[] tsRow = new String[7];
       tsRow[0] = null;
       tsRow[1] = getStorageGroupPath(devicePath).getFullPath();
-      tsRow[2] = schema.getValueTSDataTypeList().get(i).toString();
-      tsRow[3] = schema.getValueTSEncodingList().get(i).toString();
+      tsRow[2] = schema.getSubMeasurementsTSDataTypeList().get(i).toString();
+      tsRow[3] = schema.getSubMeasurementsTSEncodingList().get(i).toString();
       tsRow[4] = schema.getCompressor().toString();
       tsRow[5] = "-1";
       tsRow[6] =
@@ -1395,7 +1395,7 @@ public class MTree implements Serializable {
                   LastCacheManager.getLastTimeStamp((IMeasurementMNode) node, queryContext))
               : null;
       Pair<PartialPath, String[]> temp =
-          new Pair<>(new PartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
+          new Pair<>(new VectorPartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
       timeseriesSchemaList.add(temp);
     }
   }
@@ -1409,7 +1409,7 @@ public class MTree implements Serializable {
       String reg,
       String vectorId)
       throws StorageGroupNotSetException, IllegalPathException {
-    List<String> measurements = schema.getValueMeasurementIdList();
+    List<String> measurements = schema.getSubMeasurementsList();
     for (int i = 0; i < measurements.size(); i++) {
       if (!Pattern.matches(reg.replace("*", ".*"), measurements.get(i))) {
         continue;
@@ -1419,8 +1419,8 @@ public class MTree implements Serializable {
       String[] tsRow = new String[7];
       tsRow[0] = null;
       tsRow[1] = getStorageGroupPath(devicePath).getFullPath();
-      tsRow[2] = schema.getValueTSDataTypeList().get(i).toString();
-      tsRow[3] = schema.getValueTSEncodingList().get(i).toString();
+      tsRow[2] = schema.getSubMeasurementsTSDataTypeList().get(i).toString();
+      tsRow[3] = schema.getSubMeasurementsTSEncodingList().get(i).toString();
       tsRow[4] = schema.getCompressor().toString();
       tsRow[5] = "-1";
       tsRow[6] =
@@ -1429,7 +1429,7 @@ public class MTree implements Serializable {
                   LastCacheManager.getLastTimeStamp((IMeasurementMNode) node, queryContext))
               : null;
       Pair<PartialPath, String[]> temp =
-          new Pair<>(new PartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
+          new Pair<>(new VectorPartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
       timeseriesSchemaList.add(temp);
     }
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
index 97b3afd..524b10f 100755
--- a/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/PartialPath.java
@@ -45,6 +45,7 @@ public class PartialPath extends Path implements Comparable<Path> {
   // alias of measurement, null pointer cannot be serialized in thrift so empty string is instead
   protected String measurementAlias = "";
 
+  public PartialPath() {}
   /**
    * Construct the PartialPath using a String, will split the given String into String[] E.g., path
    * = "root.sg.\"d.1\".\"s.1\"" nodes = {"root", "sg", "\"d.1\"", "\"s.1\""}
@@ -169,6 +170,15 @@ public class PartialPath extends Path implements Comparable<Path> {
     }
   }
 
+  public PartialPath copy() {
+    PartialPath result = new PartialPath();
+    result.nodes = nodes;
+    result.fullPath = fullPath;
+    result.device = device;
+    result.measurementAlias = measurementAlias;
+    return result;
+  }
+
   @Override
   public boolean equals(Object obj) {
     if (!(obj instanceof PartialPath)) {
@@ -304,14 +314,7 @@ public class PartialPath extends Path implements Comparable<Path> {
    * If the partialPath is VectorPartialPath and it has only one sub sensor, return the sub sensor's
    * full path. Otherwise, return the partialPath's fullPath
    */
-  public static String getExactFullPath(PartialPath partialPath) {
-    String fullPath = partialPath.getFullPath();
-    if (partialPath instanceof VectorPartialPath) {
-      VectorPartialPath vectorPartialPath = (VectorPartialPath) partialPath;
-      if (vectorPartialPath.getSubSensorsPathList().size() == 1) {
-        fullPath = vectorPartialPath.getSubSensorsPathList().get(0).getFullPath();
-      }
-    }
-    return fullPath;
+  public String getExactFullPath() {
+    return getFullPath();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java b/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java
index 65ef534..b6bb353 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/VectorPartialPath.java
@@ -20,36 +20,69 @@
 package org.apache.iotdb.db.metadata;
 
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
 /**
  * VectorPartialPath represents a vector's fullPath. It not only contains the full path of vector's
- * own name, but also has subSensorsPathList which contain all the fullPath of vector's sub sensors.
+ * own name, but also has subSensorsList which contain all the fullPath of vector's sub sensors.
  * e.g. VectorPartialPath1(root.sg1.d1.vector1, [root.sg1.d1.vector1.s1, root.sg1.d1.vector1.s2])
  * VectorPartialPath2(root.sg1.d1.vector2, [root.sg1.d1.vector2.s1, root.sg1.d1.vector2.s2])
  */
 public class VectorPartialPath extends PartialPath {
 
-  private List<PartialPath> subSensorsPathList;
+  private List<String> subSensorsList;
 
-  public VectorPartialPath(String path, List<PartialPath> subSensorsPathList)
+  public VectorPartialPath() {}
+
+  public VectorPartialPath(String vectorPath, List<String> subSensorsList)
       throws IllegalPathException {
-    super(path);
-    this.subSensorsPathList = subSensorsPathList;
+    super(vectorPath);
+    this.subSensorsList = subSensorsList;
+  }
+
+  public VectorPartialPath(String vectorPath, String subSensor) throws IllegalPathException {
+    super(vectorPath);
+    subSensorsList = new ArrayList<>();
+    subSensorsList.add(subSensor);
+  }
+
+  public List<String> getSubSensorsList() {
+    return subSensorsList;
+  }
+
+  public String getSubSensor(int index) {
+    return subSensorsList.get(index);
+  }
+
+  public PartialPath getPathWithSubSensor(int index) {
+    return new PartialPath(nodes).concatNode(subSensorsList.get(index));
+  }
+
+  public void setSubSensorsList(List<String> subSensorsList) {
+    this.subSensorsList = subSensorsList;
   }
 
-  public List<PartialPath> getSubSensorsPathList() {
-    return subSensorsPathList;
+  public void addSubSensor(String subSensor) {
+    this.subSensorsList.add(subSensor);
   }
 
-  public void setSubSensorsPathList(List<PartialPath> subSensorsPathList) {
-    this.subSensorsPathList = subSensorsPathList;
+  public void addSubSensor(List<String> subSensors) {
+    this.subSensorsList.addAll(subSensors);
   }
 
-  public void addSubSensor(PartialPath path) {
-    this.subSensorsPathList.add(path);
+  @Override
+  public PartialPath copy() {
+    VectorPartialPath result = new VectorPartialPath();
+    result.nodes = nodes;
+    result.fullPath = fullPath;
+    result.device = device;
+    result.measurementAlias = measurementAlias;
+    result.subSensorsList = new ArrayList<>(subSensorsList);
+    return result;
   }
 
   @Override
@@ -64,11 +97,20 @@ public class VectorPartialPath extends PartialPath {
       return false;
     }
     VectorPartialPath that = (VectorPartialPath) o;
-    return Objects.equals(subSensorsPathList, that.subSensorsPathList);
+    return Objects.equals(subSensorsList, that.subSensorsList);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(super.hashCode(), subSensorsPathList);
+    return Objects.hash(super.hashCode(), subSensorsList);
+  }
+
+  @Override
+  public String getExactFullPath() {
+    fullPath = getFullPath();
+    if (subSensorsList.size() == 1) {
+      return fullPath + TsFileConstant.PATH_SEPARATOR + subSensorsList.get(0);
+    }
+    return fullPath;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
index 031b140..5ae627a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/lastCache/LastCacheManager.java
@@ -71,7 +71,7 @@ public class LastCacheManager {
         IMeasurementSchema schema = node.getSchema();
         if (schema instanceof VectorMeasurementSchema) {
           return lastCacheContainer.getCachedLast(
-              schema.getMeasurementIdColumnIndex(seriesPath.getMeasurement()));
+              schema.getSubMeasurementIndex(seriesPath.getMeasurement()));
         }
         return null;
       }
@@ -111,10 +111,10 @@ public class LastCacheManager {
         IMeasurementSchema schema = node.getSchema();
         if (schema instanceof VectorMeasurementSchema) {
           if (lastCacheContainer.isEmpty()) {
-            lastCacheContainer.init(schema.getMeasurementCount());
+            lastCacheContainer.init(schema.getSubMeasurementsCount());
           }
           lastCacheContainer.updateCachedLast(
-              schema.getMeasurementIdColumnIndex(seriesPath.getMeasurement()),
+              schema.getSubMeasurementIndex(seriesPath.getMeasurement()),
               timeValuePair,
               highPriorityUpdate,
               latestFlushedTime);
@@ -148,10 +148,10 @@ public class LastCacheManager {
         IMeasurementSchema schema = node.getSchema();
         if (schema instanceof VectorMeasurementSchema) {
           if (lastCacheContainer.isEmpty()) {
-            lastCacheContainer.init(schema.getMeasurementCount());
+            lastCacheContainer.init(schema.getSubMeasurementsCount());
           }
           lastCacheContainer.resetLastCache(
-              schema.getMeasurementIdColumnIndex(seriesPath.getMeasurement()));
+              schema.getSubMeasurementIndex(seriesPath.getMeasurement()));
         }
       }
     }
@@ -170,7 +170,7 @@ public class LastCacheManager {
       ILastCacheContainer lastCacheContainer = entityMNode.getLastCacheContainer(measurement);
       IMeasurementSchema schema = node.getSchema();
       if (lastCacheContainer.isEmpty() && (schema instanceof VectorMeasurementSchema)) {
-        lastCacheContainer.init(schema.getMeasurementCount());
+        lastCacheContainer.init(schema.getSubMeasurementsCount());
       }
       node.setLastCacheContainer(lastCacheContainer);
     }
@@ -261,8 +261,8 @@ public class LastCacheManager {
     TimeValuePair lastPair;
     if (schema instanceof VectorMeasurementSchema) {
       int index;
-      for (String measurement : schema.getValueMeasurementIdList()) {
-        index = schema.getMeasurementIdColumnIndex(measurement);
+      for (String measurement : schema.getSubMeasurementsList()) {
+        index = schema.getSubMeasurementIndex(measurement);
         lastPair = lastCacheContainer.getCachedLast(index);
         if (lastPair != null
             && startTime <= lastPair.getTimestamp()
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
index 1f9430a..7ea67fd 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
@@ -104,7 +104,7 @@ public class MeasurementMNode extends MNode implements IMeasurementMNode {
 
   @Override
   public int getMeasurementCount() {
-    return schema.getMeasurementCount();
+    return schema.getSubMeasurementsCount();
   }
 
   /**
@@ -118,8 +118,8 @@ public class MeasurementMNode extends MNode implements IMeasurementMNode {
     if (schema instanceof MeasurementSchema) {
       return schema.getType();
     } else {
-      int index = schema.getMeasurementIdColumnIndex(measurementId);
-      return schema.getValueTSDataTypeList().get(index);
+      int index = schema.getSubMeasurementIndex(measurementId);
+      return schema.getSubMeasurementsTSDataTypeList().get(index);
     }
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
index 5b769da..2d5b74b 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
@@ -168,7 +168,7 @@ public class Template {
       if (schemaEntry.getValue() instanceof VectorMeasurementSchema) {
         VectorMeasurementSchema vectorMeasurementSchema =
             (VectorMeasurementSchema) schemaEntry.getValue();
-        res.put(schemaEntry.getKey(), vectorMeasurementSchema.getValueMeasurementIdList());
+        res.put(schemaEntry.getKey(), vectorMeasurementSchema.getSubMeasurementsList());
       } else {
         res.put(schemaEntry.getKey(), new ArrayList<>());
       }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
index d3dff46..842850a 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/crud/QueryOperator.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.index.common.IndexType;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -260,14 +261,14 @@ public class QueryOperator extends Operator {
           }
 
           if (actualPaths.isEmpty()) {
-            String nonExistMeasurement = getMeasurementName(fullPath.getMeasurement(), aggregation);
+            String nonExistMeasurement = getMeasurementName(fullPath, aggregation);
             if (measurementSetOfGivenSuffix.add(nonExistMeasurement)) {
               measurementInfoMap.putIfAbsent(
                   nonExistMeasurement, new MeasurementInfo(MeasurementType.NonExist));
             }
           } else {
             for (PartialPath path : actualPaths) {
-              String measurementName = getMeasurementName(path.getMeasurement(), aggregation);
+              String measurementName = getMeasurementName(path, aggregation);
               TSDataType measurementDataType = IoTDB.metaManager.getSeriesType(path);
               TSDataType columnDataType = getAggregationType(aggregation);
               columnDataType = columnDataType == null ? measurementDataType : columnDataType;
@@ -372,7 +373,12 @@ public class QueryOperator extends Operator {
         : (((FunctionExpression) expression).getPaths().get(0));
   }
 
-  private String getMeasurementName(String initialMeasurement, String aggregation) {
+  private String getMeasurementName(PartialPath path, String aggregation) {
+    String initialMeasurement = path.getMeasurement();
+    if (path instanceof VectorPartialPath) {
+      String subMeasurement = ((VectorPartialPath) path).getSubSensor(0);
+      initialMeasurement += "." + subMeasurement;
+    }
     if (aggregation != null) {
       initialMeasurement = aggregation + "(" + initialMeasurement + ")";
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
index d201ae7..40ef6ca 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
@@ -281,7 +281,8 @@ public class InsertRowPlan extends InsertPlan {
         }
         // for aligned timeseries
         else {
-          for (TSDataType dataType : measurementMNodes[i].getSchema().getValueTSDataTypeList()) {
+          for (TSDataType dataType :
+              measurementMNodes[i].getSchema().getSubMeasurementsTSDataTypeList()) {
             dataTypes[columnIndex] = dataType;
             try {
               values[columnIndex] =
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/LastQueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/LastQueryPlan.java
index 4064364..21c3424 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/LastQueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/LastQueryPlan.java
@@ -24,7 +24,6 @@ import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
 import org.apache.iotdb.db.query.expression.ResultColumn;
-import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
 import org.apache.iotdb.tsfile.read.expression.impl.GlobalTimeExpression;
 import org.apache.iotdb.tsfile.read.filter.TimeFilter.TimeGt;
@@ -56,7 +55,6 @@ public class LastQueryPlan extends RawDataQueryPlan {
         columnForReaderSet.add(column);
       }
     }
-    transformPaths(IoTDB.metaManager);
     setResultColumns(deduplicatedResultColumns);
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
index 7599424..aff2b51 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/QueryPlan.java
@@ -134,7 +134,7 @@ public abstract class QueryPlan extends PhysicalPlan {
 
   public String getColumnForReaderFromPath(PartialPath path, int pathIndex) {
     ResultColumn resultColumn = resultColumns.get(pathIndex);
-    return resultColumn.hasAlias() ? resultColumn.getAlias() : path.getFullPath();
+    return resultColumn.hasAlias() ? resultColumn.getAlias() : path.getExactFullPath();
   }
 
   public String getColumnForDisplay(String columnForReader, int pathIndex)
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
index 796acc3..5936633 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/RawDataQueryPlan.java
@@ -20,12 +20,10 @@ package org.apache.iotdb.db.qp.physical.crud;
 
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
-import org.apache.iotdb.db.metadata.MManager;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.strategy.PhysicalGenerator;
-import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.read.common.Path;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
@@ -95,13 +93,7 @@ public class RawDataQueryPlan extends QueryPlan {
       }
     }
 
-    // TODO Maybe we should get VectorPartialPath above from MTree
-    // Currently, the above processing will only produce PartialPath instead of VectorPartialPath
-    // even if the queried time series is vector
-    // So, we need to transform the PartialPath to VectorPartialPath if is is a vector.
-    if (!isRawQuery()) {
-      transformPaths(IoTDB.metaManager);
-    } else {
+    if (isRawQuery()) {
       // if it is a RawQueryWithoutValueFilter, we also need to group all the subSensors of one
       // vector into one VectorPartialPath
       transformVectorPaths(physicalGenerator, columnForDisplaySet);
@@ -139,9 +131,7 @@ public class RawDataQueryPlan extends QueryPlan {
               deviceToMeasurements.computeIfAbsent(path.getDevice(), key -> new HashSet<>());
           set.add(path.getMeasurement());
           if (path instanceof VectorPartialPath) {
-            ((VectorPartialPath) path)
-                .getSubSensorsPathList()
-                .forEach(subSensor -> set.add(subSensor.getMeasurement()));
+            set.addAll(((VectorPartialPath) path).getSubSensorsList());
           }
         });
     this.deduplicatedPaths = deduplicatedPaths;
@@ -177,15 +167,6 @@ public class RawDataQueryPlan extends QueryPlan {
     return deviceToMeasurements;
   }
 
-  public void transformPaths(MManager mManager) throws MetadataException {
-    for (int i = 0; i < deduplicatedPaths.size(); i++) {
-      PartialPath path = mManager.transformPath(deduplicatedPaths.get(i));
-      if (path instanceof VectorPartialPath) {
-        deduplicatedPaths.set(i, path);
-      }
-    }
-  }
-
   /**
    * Group all the subSensors of one vector into one VectorPartialPath save the grouped
    * VectorPartialPath in deduplicatedVectorPaths and deduplicatedVectorDataTypes instead of putting
@@ -205,11 +186,12 @@ public class RawDataQueryPlan extends QueryPlan {
     setDeduplicatedVectorDataTypes(vectorizedDeduplicatedDataTypes);
 
     Map<String, Integer> columnForDisplayToQueryDataSetIndex = pair.right;
-    Map<String, Integer> pathToIndex = new HashMap<>();
+    Map<String, Integer> vectorPathToIndex = new HashMap<>();
     for (String columnForDisplay : columnForDisplaySet) {
-      pathToIndex.put(columnForDisplay, columnForDisplayToQueryDataSetIndex.get(columnForDisplay));
+      vectorPathToIndex.put(
+          columnForDisplay, columnForDisplayToQueryDataSetIndex.get(columnForDisplay));
     }
-    setVectorPathToIndex(pathToIndex);
+    setVectorPathToIndex(vectorPathToIndex);
   }
 
   public List<PartialPath> getDeduplicatedVectorPaths() {
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/AlignByDeviceDataSet.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/AlignByDeviceDataSet.java
index 923f459..86008d1 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/AlignByDeviceDataSet.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/AlignByDeviceDataSet.java
@@ -23,8 +23,7 @@ import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
 import org.apache.iotdb.db.qp.physical.crud.AlignByDevicePlan;
 import org.apache.iotdb.db.qp.physical.crud.AlignByDevicePlan.MeasurementType;
@@ -43,6 +42,9 @@ import org.apache.iotdb.tsfile.read.common.RowRecord;
 import org.apache.iotdb.tsfile.read.expression.IExpression;
 import org.apache.iotdb.tsfile.read.query.dataset.QueryDataSet;
 import org.apache.iotdb.tsfile.utils.Binary;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.VectorMeasurementSchema;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -134,7 +136,7 @@ public class AlignByDeviceDataSet extends QueryDataSet {
     while (deviceIterator.hasNext()) {
       currentDevice = deviceIterator.next();
       // get all measurements of current device
-      Set<String> measurementOfGivenDevice = getDeviceMeasurements(currentDevice);
+      Set<String> measurementOfGivenDevice = getMeasurementsUnderGivenDevice(currentDevice);
 
       // extract paths and aggregations queried from all measurements
       // executeColumns is for calculating rowRecord
@@ -156,7 +158,7 @@ public class AlignByDeviceDataSet extends QueryDataSet {
         }
         if (measurementOfGivenDevice.contains(measurement)) {
           executeColumns.add(column);
-          executePaths.add(currentDevice.concatNode(measurement));
+          executePaths.add(transformPath(currentDevice, measurement));
           tsDataTypes.add(measurementInfoMap.get(column).getMeasurementDataType());
         }
       }
@@ -177,7 +179,6 @@ public class AlignByDeviceDataSet extends QueryDataSet {
             groupByTimePlan.setDeduplicatedDataTypes(tsDataTypes);
             groupByTimePlan.setDeduplicatedAggregations(executeAggregations);
             groupByTimePlan.setExpression(expression);
-            groupByTimePlan.transformPaths(IoTDB.metaManager);
             currentDataSet = queryRouter.groupBy(groupByTimePlan, context);
             break;
           case AGGREGATE:
@@ -185,20 +186,17 @@ public class AlignByDeviceDataSet extends QueryDataSet {
             aggregationPlan.setDeduplicatedAggregations(executeAggregations);
             aggregationPlan.setDeduplicatedDataTypes(tsDataTypes);
             aggregationPlan.setExpression(expression);
-            aggregationPlan.transformPaths(IoTDB.metaManager);
             currentDataSet = queryRouter.aggregate(aggregationPlan, context);
             break;
           case FILL:
             fillQueryPlan.setDeduplicatedDataTypes(tsDataTypes);
             fillQueryPlan.setDeduplicatedPathsAndUpdate(executePaths);
-            fillQueryPlan.transformPaths(IoTDB.metaManager);
             currentDataSet = queryRouter.fill(fillQueryPlan, context);
             break;
           case QUERY:
             rawDataQueryPlan.setDeduplicatedPathsAndUpdate(executePaths);
             rawDataQueryPlan.setDeduplicatedDataTypes(tsDataTypes);
             rawDataQueryPlan.setExpression(expression);
-            rawDataQueryPlan.transformPaths(IoTDB.metaManager);
             currentDataSet = queryRouter.rawDataQuery(rawDataQueryPlan, context);
             break;
           default:
@@ -206,8 +204,7 @@ public class AlignByDeviceDataSet extends QueryDataSet {
         }
       } catch (QueryProcessException
           | QueryFilterOptimizationException
-          | StorageEngineException
-          | MetadataException e) {
+          | StorageEngineException e) {
         throw new IOException(e);
       }
 
@@ -227,17 +224,20 @@ public class AlignByDeviceDataSet extends QueryDataSet {
     return false;
   }
 
-  protected Set<String> getDeviceMeasurements(PartialPath device) throws IOException {
+  protected Set<String> getMeasurementsUnderGivenDevice(PartialPath device) throws IOException {
     try {
-      IMNode deviceNode = IoTDB.metaManager.getNodeByPath(device);
-      Set<String> res = new HashSet<>(deviceNode.getChildren().keySet());
-      for (IMNode mnode : deviceNode.getChildren().values()) {
-        res.addAll(mnode.getChildren().keySet());
-      }
-
-      Template template = deviceNode.getUpperTemplate();
-      if (template != null) {
-        res.addAll(template.getSchemaMap().keySet());
+      Set<String> res = new HashSet<>();
+      // TODO: Implement this method in Cluster MManager
+      List<IMeasurementSchema> measurementSchemas =
+          IoTDB.metaManager.getAllMeasurementByDevicePath(device);
+      for (IMeasurementSchema schema : measurementSchemas) {
+        if (schema instanceof VectorMeasurementSchema) {
+          for (String subMeasurement : schema.getSubMeasurementsList()) {
+            res.add(schema.getMeasurementId() + "." + subMeasurement);
+          }
+        } else {
+          res.add(schema.getMeasurementId());
+        }
       }
 
       return res;
@@ -246,6 +246,20 @@ public class AlignByDeviceDataSet extends QueryDataSet {
     }
   }
 
+  private PartialPath transformPath(PartialPath device, String measurement) throws IOException {
+    try {
+      PartialPath fullPath = new PartialPath(device.getFullPath(), measurement);
+      IMeasurementSchema schema = IoTDB.metaManager.getSeriesSchema(fullPath);
+      if (schema instanceof MeasurementSchema) {
+        return fullPath;
+      } else {
+        return new VectorPartialPath(fullPath.getDevice(), fullPath.getMeasurement());
+      }
+    } catch (MetadataException e) {
+      throw new IOException("Cannot get node from " + device, e);
+    }
+  }
+
   @Override
   public RowRecord nextWithoutConstraint() throws IOException {
     RowRecord originRowRecord = currentDataSet.next();
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/RawQueryDataSetWithoutValueFilter.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/RawQueryDataSetWithoutValueFilter.java
index 90a3258..5d3bec6 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/RawQueryDataSetWithoutValueFilter.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/RawQueryDataSetWithoutValueFilter.java
@@ -184,7 +184,7 @@ public class RawQueryDataSetWithoutValueFilter extends QueryDataSet
     bufferNum = 0;
     for (PartialPath path : paths) {
       if (path instanceof VectorPartialPath) {
-        bufferNum += ((VectorPartialPath) path).getSubSensorsPathList().size();
+        bufferNum += ((VectorPartialPath) path).getSubSensorsList().size();
       } else {
         bufferNum += 1;
       }
@@ -273,7 +273,7 @@ public class RawQueryDataSetWithoutValueFilter extends QueryDataSet
           if (rowOffset == 0) {
             if (paths.get(seriesIndex) instanceof VectorPartialPath) {
               for (int i = 0;
-                  i < ((VectorPartialPath) paths.get(seriesIndex)).getSubSensorsPathList().size();
+                  i < ((VectorPartialPath) paths.get(seriesIndex)).getSubSensorsList().size();
                   i++) {
                 currentBitmapList[bufferIndex] = (currentBitmapList[bufferIndex] << 1);
                 bufferIndex++;
@@ -572,7 +572,7 @@ public class RawQueryDataSetWithoutValueFilter extends QueryDataSet
           || cachedBatchDataArray[seriesIndex].currentTime() != minTime) {
         if (paths.get(seriesIndex) instanceof VectorPartialPath) {
           for (int i = 0;
-              i < ((VectorPartialPath) paths.get(seriesIndex)).getSubSensorsPathList().size();
+              i < ((VectorPartialPath) paths.get(seriesIndex)).getSubSensorsList().size();
               i++) {
             record.addField(null);
           }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
index ed9888b..0d6bfb2 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
@@ -277,8 +277,7 @@ public class LastQueryExecutor {
           // the seriesPath has been transformed to vector path
           // here needs subSensor path
           timeValuePair =
-              IoTDB.metaManager.getLastCache(
-                  ((VectorPartialPath) path).getSubSensorsPathList().get(0));
+              IoTDB.metaManager.getLastCache(((VectorPartialPath) path).getPathWithSubSensor(0));
         } else {
           timeValuePair = IoTDB.metaManager.getLastCache(path);
         }
@@ -294,8 +293,7 @@ public class LastQueryExecutor {
       if (path instanceof VectorPartialPath) {
         // the seriesPath has been transformed to vector path
         // here needs subSensor path
-        return IoTDB.metaManager.getLastCache(
-            node, ((VectorPartialPath) path).getSubSensorsPathList().get(0).getMeasurement());
+        return IoTDB.metaManager.getLastCache(node, ((VectorPartialPath) path).getSubSensor(0));
       } else {
         return IoTDB.metaManager.getLastCache(node);
       }
@@ -309,11 +307,7 @@ public class LastQueryExecutor {
           // the seriesPath has been transformed to vector path
           // here needs subSensor path
           IoTDB.metaManager.updateLastCache(
-              node,
-              ((VectorPartialPath) path).getSubSensorsPathList().get(0).getMeasurement(),
-              pair,
-              false,
-              Long.MIN_VALUE);
+              node, ((VectorPartialPath) path).getSubSensor(0), pair, false, Long.MIN_VALUE);
         } else {
           IoTDB.metaManager.updateLastCache(node, pair, false, Long.MIN_VALUE);
         }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java b/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
index 5e94afe..d2ae91f 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/executor/QueryRouter.java
@@ -20,7 +20,6 @@
 package org.apache.iotdb.db.query.executor;
 
 import org.apache.iotdb.db.exception.StorageEngineException;
-import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.AggregationPlan;
@@ -37,7 +36,6 @@ import org.apache.iotdb.db.query.dataset.groupby.GroupByFillDataSet;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByTimeDataSet;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByWithValueFilterDataSet;
 import org.apache.iotdb.db.query.dataset.groupby.GroupByWithoutValueFilterDataSet;
-import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.TimeValuePairUtils;
 import org.apache.iotdb.tsfile.exception.filter.QueryFilterOptimizationException;
 import org.apache.iotdb.tsfile.read.expression.ExpressionType;
@@ -92,11 +90,6 @@ public class QueryRouter implements IQueryRouter {
 
     if (optimizedExpression != null
         && optimizedExpression.getType() != ExpressionType.GLOBAL_TIME) {
-      try {
-        queryPlan.transformPaths(IoTDB.metaManager);
-      } catch (MetadataException e) {
-        throw new QueryProcessException(e);
-      }
       return rawDataQueryExecutor.executeWithValueFilter(context);
     } else if (optimizedExpression != null
         && optimizedExpression.getType() == ExpressionType.GLOBAL_TIME) {
diff --git a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
index 232d031..52bac21 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/expression/unary/TimeSeriesOperand.java
@@ -67,6 +67,6 @@ public class TimeSeriesOperand implements Expression {
 
   @Override
   public String toString() {
-    return path.isMeasurementAliasExists() ? path.getFullPathWithAlias() : path.getFullPath();
+    return path.isMeasurementAliasExists() ? path.getFullPathWithAlias() : path.getExactFullPath();
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/timegenerator/ServerTimeGenerator.java b/server/src/main/java/org/apache/iotdb/db/query/timegenerator/ServerTimeGenerator.java
index 645eb6b..4cd1f0b 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/timegenerator/ServerTimeGenerator.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/timegenerator/ServerTimeGenerator.java
@@ -22,7 +22,6 @@ import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
 import org.apache.iotdb.db.engine.storagegroup.StorageGroupProcessor;
 import org.apache.iotdb.db.exception.StorageEngineException;
-import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -94,12 +93,6 @@ public class ServerTimeGenerator extends TimeGenerator {
   @Override
   protected IBatchReader generateNewBatchReader(SingleSeriesExpression expression)
       throws IOException {
-    try {
-      expression.setSeriesPath(
-          IoTDB.metaManager.transformPath((PartialPath) expression.getSeriesPath()));
-    } catch (MetadataException e) {
-      throw new IOException(e);
-    }
     Filter valueFilter = expression.getFilter();
     PartialPath path = (PartialPath) expression.getSeriesPath();
     TSDataType dataType;
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
index 1e8c51f..3d2931b 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/FileLoaderUtils.java
@@ -50,7 +50,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map.Entry;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 public class FileLoaderUtils {
 
@@ -103,12 +102,7 @@ public class FileLoaderUtils {
     // deal with vector
     if (seriesPath instanceof VectorPartialPath) {
       return loadVectorTimeSeriesMetadata(
-          resource,
-          seriesPath,
-          ((VectorPartialPath) seriesPath).getSubSensorsPathList(),
-          context,
-          filter,
-          allSensors);
+          resource, (VectorPartialPath) seriesPath, context, filter, allSensors);
     }
 
     // common path
@@ -161,14 +155,13 @@ public class FileLoaderUtils {
    * Load VectorTimeSeriesMetadata for Vector
    *
    * @param resource corresponding TsFileResource
-   * @param seriesPath instance of VectorPartialPath, vector's full path, e.g. (root.sg1.d1.vector,
+   * @param vectorPath instance of VectorPartialPath, vector's full path, e.g. (root.sg1.d1.vector,
    *     [root.sg1.d1.vector.s1, root.sg1.d1.vector.s2])
-   * @param subSensorList subSensorList of the seriesPath
+   * @param allSensors all sensors belonging to this device that appear in query
    */
   private static VectorTimeSeriesMetadata loadVectorTimeSeriesMetadata(
       TsFileResource resource,
-      PartialPath seriesPath,
-      List<PartialPath> subSensorList,
+      VectorPartialPath vectorPath,
       QueryContext context,
       Filter filter,
       Set<String> allSensors)
@@ -187,11 +180,9 @@ public class FileLoaderUtils {
               .get(
                   new TimeSeriesMetadataCache.TimeSeriesMetadataCacheKey(
                       resource.getTsFilePath(),
-                      seriesPath.getDevice(),
-                      seriesPath.getMeasurement()),
-                  subSensorList.stream()
-                      .map(PartialPath::getMeasurement)
-                      .collect(Collectors.toList()),
+                      vectorPath.getDevice(),
+                      vectorPath.getMeasurement()),
+                  new ArrayList<>(vectorPath.getSubSensorsList()),
                   allSensors,
                   context.isDebug());
 
@@ -200,12 +191,13 @@ public class FileLoaderUtils {
         timeSeriesMetadata
             .get(0)
             .setChunkMetadataLoader(
-                new DiskChunkMetadataLoader(resource, seriesPath, context, filter));
+                new DiskChunkMetadataLoader(resource, vectorPath, context, filter));
         for (int i = 1; i < timeSeriesMetadata.size(); i++) {
+          PartialPath subPath = vectorPath.getPathWithSubSensor(i - 1);
           timeSeriesMetadata
               .get(i)
               .setChunkMetadataLoader(
-                  new DiskChunkMetadataLoader(resource, subSensorList.get(i - 1), context, filter));
+                  new DiskChunkMetadataLoader(resource, subPath, context, filter));
         }
         vectorTimeSeriesMetadata =
             new VectorTimeSeriesMetadata(
@@ -216,13 +208,13 @@ public class FileLoaderUtils {
       vectorTimeSeriesMetadata = (VectorTimeSeriesMetadata) resource.getTimeSeriesMetadata();
       if (vectorTimeSeriesMetadata != null) {
         vectorTimeSeriesMetadata.setChunkMetadataLoader(
-            new MemChunkMetadataLoader(resource, seriesPath, context, filter));
+            new MemChunkMetadataLoader(resource, vectorPath, context, filter));
       }
     }
 
     if (vectorTimeSeriesMetadata != null) {
       List<Modification> pathModifications =
-          context.getPathModifications(resource.getModFile(), seriesPath);
+          context.getPathModifications(resource.getModFile(), vectorPath);
       vectorTimeSeriesMetadata.getTimeseriesMetadata().setModified(!pathModifications.isEmpty());
       if (vectorTimeSeriesMetadata.getTimeseriesMetadata().getStatistics().getStartTime()
           > vectorTimeSeriesMetadata.getTimeseriesMetadata().getStatistics().getEndTime()) {
@@ -238,7 +230,7 @@ public class FileLoaderUtils {
           vectorTimeSeriesMetadata.getValueTimeseriesMetadataList();
       for (int i = 0; i < valueTimeSeriesMetadataList.size(); i++) {
         pathModifications =
-            context.getPathModifications(resource.getModFile(), subSensorList.get(i));
+            context.getPathModifications(resource.getModFile(), vectorPath.getPathWithSubSensor(i));
         valueTimeSeriesMetadataList.get(i).setModified(!pathModifications.isEmpty());
       }
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
index 667a984..564c39d 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
@@ -112,7 +112,7 @@ public class MemUtils {
         // time and index column memSize
         memSize += (end - start) * (8L + 4L);
         // value columns memSize
-        for (TSDataType type : schema.getValueTSDataTypeList()) {
+        for (TSDataType type : schema.getSubMeasurementsTSDataTypeList()) {
           if (type == TSDataType.TEXT && addingTextDataSize) {
             for (int j = start; j < end; j++) {
               memSize += getBinarySize(((Binary[]) insertTabletPlan.getColumns()[columnCount])[j]);
diff --git a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
index 61d7692..1e7c0a6 100644
--- a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
+++ b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
@@ -199,7 +199,7 @@ public class LogReplayer {
                     + tPlan.getMeasurements()[i]));
         columnIndex++;
       } else if (tPlan.isAligned()) {
-        List<TSDataType> datatypes = mNodes[i].getSchema().getValueTSDataTypeList();
+        List<TSDataType> datatypes = mNodes[i].getSchema().getSubMeasurementsTSDataTypeList();
         for (int j = 0; j < datatypes.size(); j++) {
           if (tPlan.getDataTypes()[columnIndex] == null) {
             tPlan.getDataTypes()[columnIndex] = datatypes.get(j);
@@ -207,7 +207,7 @@ public class LogReplayer {
             tPlan.markFailedMeasurementInsertion(
                 i,
                 new DataTypeMismatchException(
-                    mNodes[i].getSchema().getValueMeasurementIdList().get(j),
+                    mNodes[i].getSchema().getSubMeasurementsList().get(j),
                     tPlan.getDataTypes()[columnIndex],
                     datatypes.get(j)));
           }
diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java
index 039c186..2336142 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -1328,10 +1328,10 @@ public class Session {
       request.setIsAligned(true);
       IMeasurementSchema measurementSchema = tablet.getSchemas().get(0);
       request.setPrefixPath(tablet.prefixPath);
-      int measurementsSize = measurementSchema.getValueMeasurementIdList().size();
+      int measurementsSize = measurementSchema.getSubMeasurementsList().size();
       for (int i = 0; i < measurementsSize; i++) {
-        request.addToMeasurements(measurementSchema.getValueMeasurementIdList().get(i));
-        request.addToTypes(measurementSchema.getValueTSDataTypeList().get(i).ordinal());
+        request.addToMeasurements(measurementSchema.getSubMeasurementsList().get(i));
+        request.addToTypes(measurementSchema.getSubMeasurementsTSDataTypeList().get(i).ordinal());
       }
       request.setIsAligned(true);
     } else {
@@ -1741,10 +1741,13 @@ public class Session {
         }
         columnIndex++;
       } else {
-        int measurementSize = schema.getValueMeasurementIdList().size();
+        int measurementSize = schema.getSubMeasurementsList().size();
         for (int j = 0; j < measurementSize; j++) {
           tablet.values[columnIndex] =
-              sortList(tablet.values[columnIndex], schema.getValueTSDataTypeList().get(j), index);
+              sortList(
+                  tablet.values[columnIndex],
+                  schema.getSubMeasurementsTSDataTypeList().get(j),
+                  index);
           if (tablet.bitMaps != null && tablet.bitMaps[columnIndex] != null) {
             tablet.bitMaps[columnIndex] = sortBitMap(tablet.bitMaps[columnIndex], index);
           }
diff --git a/session/src/main/java/org/apache/iotdb/session/SessionUtils.java b/session/src/main/java/org/apache/iotdb/session/SessionUtils.java
index f50ad52..4080688 100644
--- a/session/src/main/java/org/apache/iotdb/session/SessionUtils.java
+++ b/session/src/main/java/org/apache/iotdb/session/SessionUtils.java
@@ -58,9 +58,9 @@ public class SessionUtils {
         getValueBufferOfDataType(schema.getType(), tablet, indexOfValues, valueBuffer);
         indexOfValues++;
       } else {
-        for (int j = 0; j < schema.getValueTSDataTypeList().size(); j++) {
+        for (int j = 0; j < schema.getSubMeasurementsTSDataTypeList().size(); j++) {
           getValueBufferOfDataType(
-              schema.getValueTSDataTypeList().get(j), tablet, indexOfValues, valueBuffer);
+              schema.getSubMeasurementsTSDataTypeList().get(j), tablet, indexOfValues, valueBuffer);
           indexOfValues++;
         }
       }
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
index 2dd9230..fd14315 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
@@ -58,7 +58,11 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class IoTDBSessionSimpleIT {
 
@@ -392,15 +396,15 @@ public class IoTDBSessionSimpleIT {
       int rowIndex = tablet.rowSize++;
       tablet.addTimestamp(rowIndex, timestamp);
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(0),
+          schemaList.get(0).getSubMeasurementsList().get(0),
           rowIndex,
           new SecureRandom().nextLong());
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(1),
+          schemaList.get(0).getSubMeasurementsList().get(1),
           rowIndex,
           new SecureRandom().nextInt());
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(2), rowIndex, new Binary("test"));
+          schemaList.get(0).getSubMeasurementsList().get(2), rowIndex, new Binary("test"));
       timestamp++;
     }
 
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionVectorIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionVectorIT.java
index f3f781a..ac90003 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionVectorIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionVectorIT.java
@@ -170,10 +170,9 @@ public class IoTDBSessionVectorIT {
     for (long row = 0; row < 100; row++) {
       int rowIndex = tablet.rowSize++;
       tablet.addTimestamp(rowIndex, timestamp);
+      tablet.addValue(schemaList.get(0).getSubMeasurementsList().get(0), rowIndex, row * 10 + 1L);
       tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(0), rowIndex, row * 10 + 1L);
-      tablet.addValue(
-          schemaList.get(0).getValueMeasurementIdList().get(1), rowIndex, (int) (row * 10 + 2));
+          schemaList.get(0).getSubMeasurementsList().get(1), rowIndex, (int) (row * 10 + 2));
 
       if (tablet.rowSize == tablet.getMaxRowNumber()) {
         session.insertTablet(tablet, true);
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/ChunkGroupWriterImpl.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/ChunkGroupWriterImpl.java
index 65bc9c7..4d82175 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/ChunkGroupWriterImpl.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/ChunkGroupWriterImpl.java
@@ -108,7 +108,7 @@ public class ChunkGroupWriterImpl implements IChunkGroupWriter {
     int batchSize = tablet.rowSize;
     VectorMeasurementSchema vectorMeasurementSchema =
         (VectorMeasurementSchema) tablet.getSchemas().get(index);
-    List<TSDataType> valueDataTypes = vectorMeasurementSchema.getValueTSDataTypeList();
+    List<TSDataType> valueDataTypes = vectorMeasurementSchema.getSubMeasurementsTSDataTypeList();
     IChunkWriter vectorChunkWriter = chunkWriters.get(measurement);
     for (int row = 0; row < batchSize; row++) {
       long time = tablet.timestamps[row];
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/VectorChunkWriterImpl.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/VectorChunkWriterImpl.java
index 83faad4..c661cbe 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/VectorChunkWriterImpl.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/chunk/VectorChunkWriterImpl.java
@@ -45,10 +45,10 @@ public class VectorChunkWriterImpl implements IChunkWriter {
             schema.getTimeTSEncoding(),
             schema.getTimeEncoder());
 
-    List<String> valueMeasurementIdList = schema.getValueMeasurementIdList();
-    List<TSDataType> valueTSDataTypeList = schema.getValueTSDataTypeList();
-    List<TSEncoding> valueTSEncodingList = schema.getValueTSEncodingList();
-    List<Encoder> valueEncoderList = schema.getValueEncoderList();
+    List<String> valueMeasurementIdList = schema.getSubMeasurementsList();
+    List<TSDataType> valueTSDataTypeList = schema.getSubMeasurementsTSDataTypeList();
+    List<TSEncoding> valueTSEncodingList = schema.getSubMeasurementsTSEncodingList();
+    List<Encoder> valueEncoderList = schema.getSubMeasurementsEncoderList();
 
     valueChunkWriterList = new ArrayList<>(valueMeasurementIdList.size());
     for (int i = 0; i < valueMeasurementIdList.size(); i++) {
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
index 2c8d958..bbe91fb 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/record/Tablet.java
@@ -98,7 +98,7 @@ public class Tablet {
     int indexInSchema = 0;
     for (IMeasurementSchema schema : schemas) {
       if (schema.getType() == TSDataType.VECTOR) {
-        for (String measurementId : schema.getValueMeasurementIdList()) {
+        for (String measurementId : schema.getSubMeasurementsList()) {
           measurementIndex.put(measurementId, indexInSchema);
         }
       } else {
@@ -124,8 +124,8 @@ public class Tablet {
     int indexOfSchema = measurementIndex.get(measurementId);
     IMeasurementSchema measurementSchema = schemas.get(indexOfSchema);
     if (measurementSchema.getType().equals(TSDataType.VECTOR)) {
-      int indexInVector = measurementSchema.getMeasurementIdColumnIndex(measurementId);
-      TSDataType dataType = measurementSchema.getValueTSDataTypeList().get(indexInVector);
+      int indexInVector = measurementSchema.getSubMeasurementIndex(measurementId);
+      TSDataType dataType = measurementSchema.getSubMeasurementsTSDataTypeList().get(indexInVector);
       addValueOfDataType(dataType, rowIndex, indexInVector, value);
     } else {
       addValueOfDataType(measurementSchema.getType(), rowIndex, indexOfSchema, value);
@@ -210,7 +210,7 @@ public class Tablet {
     int valueColumnsSize = 0;
     for (IMeasurementSchema schema : schemas) {
       if (schema instanceof VectorMeasurementSchema) {
-        valueColumnsSize += schema.getValueMeasurementIdList().size();
+        valueColumnsSize += schema.getSubMeasurementsList().size();
       } else {
         valueColumnsSize++;
       }
@@ -231,8 +231,8 @@ public class Tablet {
   }
 
   private int buildVectorColumns(VectorMeasurementSchema schema, int idx) {
-    for (int i = 0; i < schema.getValueMeasurementIdList().size(); i++) {
-      TSDataType dataType = schema.getValueTSDataTypeList().get(i);
+    for (int i = 0; i < schema.getSubMeasurementsList().size(); i++) {
+      TSDataType dataType = schema.getSubMeasurementsTSDataTypeList().get(i);
       values[idx] = createValueColumnOfDataType(dataType);
       idx++;
     }
@@ -281,8 +281,8 @@ public class Tablet {
         valueOccupation += calOccupationOfOneColumn(schema.getType(), columnIndex);
         columnIndex++;
       } else {
-        for (int j = 0; j < schema.getValueTSDataTypeList().size(); j++) {
-          TSDataType dataType = schema.getValueTSDataTypeList().get(j);
+        for (int j = 0; j < schema.getSubMeasurementsTSDataTypeList().size(); j++) {
+          TSDataType dataType = schema.getSubMeasurementsTSDataTypeList().get(j);
           valueOccupation += calOccupationOfOneColumn(dataType, columnIndex);
           columnIndex++;
         }
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/IMeasurementSchema.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/IMeasurementSchema.java
index b689a12..5680d0e 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/IMeasurementSchema.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/IMeasurementSchema.java
@@ -49,20 +49,20 @@ public interface IMeasurementSchema {
 
   Map<String, String> getProps();
 
-  List<String> getValueMeasurementIdList();
+  List<String> getSubMeasurementsList();
 
-  List<TSDataType> getValueTSDataTypeList();
+  List<TSDataType> getSubMeasurementsTSDataTypeList();
 
-  List<TSEncoding> getValueTSEncodingList();
+  List<TSEncoding> getSubMeasurementsTSEncodingList();
 
-  List<Encoder> getValueEncoderList();
+  List<Encoder> getSubMeasurementsEncoderList();
 
-  int getMeasurementIdColumnIndex(String measurementId);
+  int getSubMeasurementIndex(String measurementId);
 
-  int getMeasurementCount();
+  int getSubMeasurementsCount();
 
   /* test whether the schema contains Measurement with given measurementId */
-  boolean isCompatible(String measurementId);
+  boolean containsSubMeasurement(String measurementId);
 
   int serializeTo(ByteBuffer buffer);
 
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/MeasurementSchema.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/MeasurementSchema.java
index 6a5e2a6..7cdffee 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/MeasurementSchema.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/MeasurementSchema.java
@@ -222,22 +222,22 @@ public class MeasurementSchema
   }
 
   @Override
-  public List<String> getValueMeasurementIdList() {
+  public List<String> getSubMeasurementsList() {
     throw new UnsupportedOperationException("unsupported method for MeasurementSchema");
   }
 
   @Override
-  public List<TSDataType> getValueTSDataTypeList() {
+  public List<TSDataType> getSubMeasurementsTSDataTypeList() {
     throw new UnsupportedOperationException("unsupported method for MeasurementSchema");
   }
 
   @Override
-  public List<TSEncoding> getValueTSEncodingList() {
+  public List<TSEncoding> getSubMeasurementsTSEncodingList() {
     throw new UnsupportedOperationException("unsupported method for MeasurementSchema");
   }
 
   @Override
-  public List<Encoder> getValueEncoderList() {
+  public List<Encoder> getSubMeasurementsEncoderList() {
     throw new UnsupportedOperationException("unsupported method for MeasurementSchema");
   }
 
@@ -392,17 +392,17 @@ public class MeasurementSchema
   }
 
   @Override
-  public int getMeasurementIdColumnIndex(String measurementId) {
+  public int getSubMeasurementIndex(String measurementId) {
     return this.measurementId.equals(measurementId) ? 0 : -1;
   }
 
   @Override
-  public int getMeasurementCount() {
+  public int getSubMeasurementsCount() {
     return 1;
   }
 
   @Override
-  public boolean isCompatible(String measurementId) {
+  public boolean containsSubMeasurement(String measurementId) {
     return this.measurementId.equals(measurementId);
   }
 }
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/VectorMeasurementSchema.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/VectorMeasurementSchema.java
index 280ba25..22e2159 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/VectorMeasurementSchema.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/write/schema/VectorMeasurementSchema.java
@@ -43,8 +43,8 @@ import java.util.Objects;
 public class VectorMeasurementSchema
     implements IMeasurementSchema, Comparable<VectorMeasurementSchema>, Serializable {
 
-  private String vectorMeausurementId;
-  private Map<String, Integer> measurementsToIndexMap;
+  private String vectorMeasurementId;
+  private Map<String, Integer> subMeasurementsToIndexMap;
   private byte[] types;
   private byte[] encodings;
   private TSEncodingBuilder[] encodingConverters;
@@ -53,15 +53,15 @@ public class VectorMeasurementSchema
   public VectorMeasurementSchema() {}
 
   public VectorMeasurementSchema(
-      String measurementId,
-      String[] measurements,
+      String vectorMeasurementId,
+      String[] subMeasurements,
       TSDataType[] types,
       TSEncoding[] encodings,
       CompressionType compressionType) {
-    this.vectorMeausurementId = measurementId;
-    this.measurementsToIndexMap = new HashMap<>();
-    for (int i = 0; i < measurements.length; i++) {
-      measurementsToIndexMap.put(measurements[i], i);
+    this.vectorMeasurementId = vectorMeasurementId;
+    this.subMeasurementsToIndexMap = new HashMap<>();
+    for (int i = 0; i < subMeasurements.length; i++) {
+      subMeasurementsToIndexMap.put(subMeasurements[i], i);
     }
     byte[] typesInByte = new byte[types.length];
     for (int i = 0; i < types.length; i++) {
@@ -74,15 +74,16 @@ public class VectorMeasurementSchema
       encodingsInByte[i] = encodings[i].serialize();
     }
     this.encodings = encodingsInByte;
-    this.encodingConverters = new TSEncodingBuilder[measurements.length];
+    this.encodingConverters = new TSEncodingBuilder[subMeasurements.length];
     this.compressor = compressionType.serialize();
   }
 
-  public VectorMeasurementSchema(String measurementId, String[] measurements, TSDataType[] types) {
-    this.vectorMeausurementId = measurementId;
-    this.measurementsToIndexMap = new HashMap<>();
-    for (int i = 0; i < measurements.length; i++) {
-      measurementsToIndexMap.put(measurements[i], i);
+  public VectorMeasurementSchema(
+      String vectorMeasurementId, String[] subMeasurements, TSDataType[] types) {
+    this.vectorMeasurementId = vectorMeasurementId;
+    this.subMeasurementsToIndexMap = new HashMap<>();
+    for (int i = 0; i < subMeasurements.length; i++) {
+      subMeasurementsToIndexMap.put(subMeasurements[i], i);
     }
     this.types = new byte[types.length];
     for (int i = 0; i < types.length; i++) {
@@ -95,15 +96,18 @@ public class VectorMeasurementSchema
           TSEncoding.valueOf(TSFileDescriptor.getInstance().getConfig().getValueEncoder())
               .serialize();
     }
-    this.encodingConverters = new TSEncodingBuilder[measurements.length];
+    this.encodingConverters = new TSEncodingBuilder[subMeasurements.length];
     this.compressor = TSFileDescriptor.getInstance().getConfig().getCompressor().serialize();
   }
 
   public VectorMeasurementSchema(
-      String measurementId, String[] measurements, TSDataType[] types, TSEncoding[] encodings) {
+      String vectorMeasurementId,
+      String[] subMeasurements,
+      TSDataType[] types,
+      TSEncoding[] encodings) {
     this(
-        measurementId,
-        measurements,
+        vectorMeasurementId,
+        subMeasurements,
         types,
         encodings,
         TSFileDescriptor.getInstance().getConfig().getCompressor());
@@ -111,7 +115,7 @@ public class VectorMeasurementSchema
 
   @Override
   public String getMeasurementId() {
-    return vectorMeausurementId;
+    return vectorMeasurementId;
   }
 
   @Override
@@ -158,16 +162,16 @@ public class VectorMeasurementSchema
   }
 
   @Override
-  public List<String> getValueMeasurementIdList() {
-    String[] measurements = new String[measurementsToIndexMap.size()];
-    for (Map.Entry<String, Integer> entry : measurementsToIndexMap.entrySet()) {
+  public List<String> getSubMeasurementsList() {
+    String[] measurements = new String[subMeasurementsToIndexMap.size()];
+    for (Map.Entry<String, Integer> entry : subMeasurementsToIndexMap.entrySet()) {
       measurements[entry.getValue()] = entry.getKey();
     }
     return Arrays.asList(measurements);
   }
 
   @Override
-  public List<TSDataType> getValueTSDataTypeList() {
+  public List<TSDataType> getSubMeasurementsTSDataTypeList() {
     List<TSDataType> dataTypeList = new ArrayList<>();
     for (byte dataType : types) {
       dataTypeList.add(TSDataType.deserialize(dataType));
@@ -176,7 +180,7 @@ public class VectorMeasurementSchema
   }
 
   @Override
-  public List<TSEncoding> getValueTSEncodingList() {
+  public List<TSEncoding> getSubMeasurementsTSEncodingList() {
     List<TSEncoding> encodingList = new ArrayList<>();
     for (byte encoding : encodings) {
       encodingList.add(TSEncoding.deserialize(encoding));
@@ -185,7 +189,7 @@ public class VectorMeasurementSchema
   }
 
   @Override
-  public List<Encoder> getValueEncoderList() {
+  public List<Encoder> getSubMeasurementsEncoderList() {
     List<Encoder> encoderList = new ArrayList<>();
     for (int i = 0; i < encodings.length; i++) {
       TSEncoding encoding = TSEncoding.deserialize(encodings[i]);
@@ -201,27 +205,27 @@ public class VectorMeasurementSchema
   }
 
   @Override
-  public int getMeasurementIdColumnIndex(String measurementId) {
-    return measurementsToIndexMap.getOrDefault(measurementId, -1);
+  public int getSubMeasurementIndex(String subMeasurement) {
+    return subMeasurementsToIndexMap.getOrDefault(subMeasurement, -1);
   }
 
   @Override
-  public int getMeasurementCount() {
-    return measurementsToIndexMap.size();
+  public int getSubMeasurementsCount() {
+    return subMeasurementsToIndexMap.size();
   }
 
   @Override
-  public boolean isCompatible(String measurementId) {
-    return measurementsToIndexMap.containsKey(measurementId);
+  public boolean containsSubMeasurement(String subMeasurement) {
+    return subMeasurementsToIndexMap.containsKey(subMeasurement);
   }
 
   @Override
   public int serializeTo(ByteBuffer buffer) {
     int byteLen = 0;
-    byteLen += ReadWriteIOUtils.write(vectorMeausurementId, buffer);
-    byteLen += ReadWriteIOUtils.write(measurementsToIndexMap.size(), buffer);
+    byteLen += ReadWriteIOUtils.write(vectorMeasurementId, buffer);
+    byteLen += ReadWriteIOUtils.write(subMeasurementsToIndexMap.size(), buffer);
 
-    for (Map.Entry<String, Integer> entry : measurementsToIndexMap.entrySet()) {
+    for (Map.Entry<String, Integer> entry : subMeasurementsToIndexMap.entrySet()) {
       byteLen += ReadWriteIOUtils.write(entry.getKey(), buffer);
       byteLen += ReadWriteIOUtils.write(entry.getValue(), buffer);
     }
@@ -239,10 +243,10 @@ public class VectorMeasurementSchema
   @Override
   public int serializeTo(OutputStream outputStream) throws IOException {
     int byteLen = 0;
-    byteLen += ReadWriteIOUtils.write(vectorMeausurementId, outputStream);
-    byteLen += ReadWriteIOUtils.write(measurementsToIndexMap.size(), outputStream);
+    byteLen += ReadWriteIOUtils.write(vectorMeasurementId, outputStream);
+    byteLen += ReadWriteIOUtils.write(subMeasurementsToIndexMap.size(), outputStream);
 
-    for (Map.Entry<String, Integer> entry : measurementsToIndexMap.entrySet()) {
+    for (Map.Entry<String, Integer> entry : subMeasurementsToIndexMap.entrySet()) {
       byteLen += ReadWriteIOUtils.write(entry.getKey(), outputStream);
       byteLen += ReadWriteIOUtils.write(entry.getValue(), outputStream);
     }
@@ -276,7 +280,7 @@ public class VectorMeasurementSchema
   public static VectorMeasurementSchema deserializeFrom(InputStream inputStream)
       throws IOException {
     VectorMeasurementSchema vectorMeasurementSchema = new VectorMeasurementSchema();
-    vectorMeasurementSchema.vectorMeausurementId = ReadWriteIOUtils.readString(inputStream);
+    vectorMeasurementSchema.vectorMeasurementId = ReadWriteIOUtils.readString(inputStream);
 
     int measurementSize = ReadWriteIOUtils.readInt(inputStream);
     Map<String, Integer> measurementsToIndexMap = new HashMap<>();
@@ -284,7 +288,7 @@ public class VectorMeasurementSchema
       measurementsToIndexMap.put(
           ReadWriteIOUtils.readString(inputStream), ReadWriteIOUtils.readInt(inputStream));
     }
-    vectorMeasurementSchema.measurementsToIndexMap = measurementsToIndexMap;
+    vectorMeasurementSchema.subMeasurementsToIndexMap = measurementsToIndexMap;
 
     byte[] types = new byte[measurementSize];
     for (int i = 0; i < measurementSize; i++) {
@@ -304,14 +308,14 @@ public class VectorMeasurementSchema
 
   public static VectorMeasurementSchema deserializeFrom(ByteBuffer buffer) {
     VectorMeasurementSchema vectorMeasurementSchema = new VectorMeasurementSchema();
-    vectorMeasurementSchema.vectorMeausurementId = ReadWriteIOUtils.readString(buffer);
+    vectorMeasurementSchema.vectorMeasurementId = ReadWriteIOUtils.readString(buffer);
     int measurementSize = ReadWriteIOUtils.readInt(buffer);
     Map<String, Integer> measurementsToIndexMap = new HashMap<>();
     for (int i = 0; i < measurementSize; i++) {
       measurementsToIndexMap.put(
           ReadWriteIOUtils.readString(buffer), ReadWriteIOUtils.readInt(buffer));
     }
-    vectorMeasurementSchema.measurementsToIndexMap = measurementsToIndexMap;
+    vectorMeasurementSchema.subMeasurementsToIndexMap = measurementsToIndexMap;
 
     byte[] types = new byte[measurementSize];
     for (int i = 0; i < measurementSize; i++) {
@@ -340,13 +344,13 @@ public class VectorMeasurementSchema
     VectorMeasurementSchema that = (VectorMeasurementSchema) o;
     return Arrays.equals(types, that.types)
         && Arrays.equals(encodings, that.encodings)
-        && Objects.equals(vectorMeausurementId, that.vectorMeausurementId)
+        && Objects.equals(vectorMeasurementId, that.vectorMeasurementId)
         && Objects.equals(compressor, that.compressor);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(vectorMeausurementId, types, encodings, compressor);
+    return Objects.hash(vectorMeasurementId, types, encodings, compressor);
   }
 
   /** compare by vector name */
@@ -355,16 +359,16 @@ public class VectorMeasurementSchema
     if (equals(o)) {
       return 0;
     } else {
-      return this.vectorMeausurementId.compareTo(o.vectorMeausurementId);
+      return this.vectorMeasurementId.compareTo(o.vectorMeasurementId);
     }
   }
 
   @Override
   public String toString() {
     StringContainer sc = new StringContainer("");
-    sc.addTail(vectorMeausurementId, ",");
+    sc.addTail(vectorMeasurementId, ",");
     // string is not in real order
-    for (Map.Entry<String, Integer> entry : measurementsToIndexMap.entrySet()) {
+    for (Map.Entry<String, Integer> entry : subMeasurementsToIndexMap.entrySet()) {
       sc.addTail(
           "[",
           entry.getKey(),
diff --git a/tsfile/src/test/java/org/apache/iotdb/tsfile/write/writer/VectorMeasurementSchemaStub.java b/tsfile/src/test/java/org/apache/iotdb/tsfile/write/writer/VectorMeasurementSchemaStub.java
index de9c4a0..5e499d5 100644
--- a/tsfile/src/test/java/org/apache/iotdb/tsfile/write/writer/VectorMeasurementSchemaStub.java
+++ b/tsfile/src/test/java/org/apache/iotdb/tsfile/write/writer/VectorMeasurementSchemaStub.java
@@ -79,22 +79,22 @@ public class VectorMeasurementSchemaStub implements IMeasurementSchema {
   }
 
   @Override
-  public List<String> getValueMeasurementIdList() {
+  public List<String> getSubMeasurementsList() {
     return Arrays.asList("s1", "s2", "s3");
   }
 
   @Override
-  public List<TSDataType> getValueTSDataTypeList() {
+  public List<TSDataType> getSubMeasurementsTSDataTypeList() {
     return Arrays.asList(TSDataType.FLOAT, TSDataType.INT32, TSDataType.DOUBLE);
   }
 
   @Override
-  public List<TSEncoding> getValueTSEncodingList() {
+  public List<TSEncoding> getSubMeasurementsTSEncodingList() {
     return Arrays.asList(TSEncoding.PLAIN, TSEncoding.PLAIN, TSEncoding.PLAIN);
   }
 
   @Override
-  public List<Encoder> getValueEncoderList() {
+  public List<Encoder> getSubMeasurementsEncoderList() {
     return Arrays.asList(
         new PlainEncoder(TSDataType.FLOAT, 0),
         new PlainEncoder(TSDataType.INT32, 0),
@@ -122,17 +122,17 @@ public class VectorMeasurementSchemaStub implements IMeasurementSchema {
   }
 
   @Override
-  public int getMeasurementIdColumnIndex(String measurementId) {
+  public int getSubMeasurementIndex(String measurementId) {
     return 0;
   }
 
   @Override
-  public int getMeasurementCount() {
+  public int getSubMeasurementsCount() {
     return 0;
   }
 
   @Override
-  public boolean isCompatible(String measurementId) {
+  public boolean containsSubMeasurement(String measurementId) {
     return false;
   }
 }