Search in sources :

Example 1 with TiIndexInfo

use of com.pingcap.tikv.meta.TiIndexInfo in project tispark by pingcap.

the class TiKVScanAnalyzer method buildTiDAGReq.

// Build scan plan picking access path with lowest cost by estimation
public TiDAGRequest buildTiDAGReq(boolean allowIndexScan, boolean useIndexScanFirst, boolean canUseTiKV, boolean canUseTiFlash, List<TiColumnInfo> columnList, List<Expression> conditions, TiTableInfo table, TableStatistics tableStatistics, TiTimestamp ts, TiDAGRequest dagRequest) {
    TiKVScanPlan minPlan = null;
    if (canUseTiKV) {
        minPlan = buildTableScan(conditions, table, tableStatistics);
    }
    if (canUseTiFlash) {
        // it is possible that only TiFlash plan exists due to isolation read.
        TiKVScanPlan plan = buildTiFlashScan(columnList, conditions, table, tableStatistics);
        if (minPlan == null || plan.getCost() < minPlan.getCost()) {
            minPlan = plan;
        }
    } else if (canUseTiKV && allowIndexScan) {
        minPlan.getFilters().forEach(dagRequest::addDowngradeFilter);
        if (table.isPartitionEnabled()) {
        // disable index scan
        } else {
            TiKVScanPlan minIndexPlan = null;
            double minIndexCost = Double.MAX_VALUE;
            for (TiIndexInfo index : table.getIndices()) {
                if (table.isCommonHandle() && table.getPrimaryKey().equals(index)) {
                    continue;
                }
                if (supportIndexScan(index, table)) {
                    TiKVScanPlan plan = buildIndexScan(columnList, conditions, index, table, tableStatistics, false);
                    if (plan.getCost() < minIndexCost) {
                        minIndexPlan = plan;
                        minIndexCost = plan.getCost();
                    }
                }
            }
            if (minIndexPlan != null && (minIndexCost < minPlan.getCost() || useIndexScanFirst)) {
                minPlan = minIndexPlan;
            }
        }
    }
    if (minPlan == null) {
        throw new TiClientInternalException("No valid plan found for table '" + table.getName() + "'");
    }
    TiStoreType minPlanStoreType = minPlan.getStoreType();
    // TiKV should not use CHBlock as Encode Type.
    if (minPlanStoreType == TiStoreType.TiKV && dagRequest.getEncodeType() == EncodeType.TypeCHBlock) {
        dagRequest.setEncodeType(EncodeType.TypeChunk);
    }
    // Set DAG Request's store type as minPlan's store type.
    dagRequest.setStoreType(minPlanStoreType);
    dagRequest.addRanges(minPlan.getKeyRanges());
    dagRequest.setPrunedParts(minPlan.getPrunedParts());
    dagRequest.addFilters(new ArrayList<>(minPlan.getFilters()));
    if (minPlan.isIndexScan()) {
        dagRequest.setIndexInfo(minPlan.getIndex());
        // need to set isDoubleRead to true for dagRequest in case of double read
        dagRequest.setIsDoubleRead(minPlan.isDoubleRead());
    }
    dagRequest.setTableInfo(table);
    dagRequest.setStartTs(ts);
    dagRequest.setEstimatedCount(minPlan.getEstimatedRowCount());
    return dagRequest;
}
Also used : TiStoreType(com.pingcap.tikv.region.TiStoreType) TiClientInternalException(com.pingcap.tikv.exception.TiClientInternalException) TiIndexInfo(com.pingcap.tikv.meta.TiIndexInfo)

Example 2 with TiIndexInfo

use of com.pingcap.tikv.meta.TiIndexInfo in project tispark by pingcap.

the class TiKVScanAnalyzerTest method buildIndexScanKeyRangeTest.

@Test
public void buildIndexScanKeyRangeTest() {
    TiTableInfo table = createTableWithIndex(6, 5);
    TiIndexInfo index = table.getIndices().get(0);
    Expression eq1 = equal(ColumnRef.create("c1", table), Constant.create(0));
    Expression eq2 = lessEqual(ColumnRef.create("c2", table), Constant.create("wtf"));
    List<Expression> exprs = ImmutableList.of(eq1);
    ScanSpec result = TiKVScanAnalyzer.extractConditions(exprs, table, index);
    List<IndexRange> irs = expressionToIndexRanges(result.getPointPredicates(), result.getRangePredicate(), table, index);
    TiKVScanAnalyzer scanAnalyzer = new TiKVScanAnalyzer();
    Map<Long, List<Coprocessor.KeyRange>> keyRanges = scanAnalyzer.buildIndexScanKeyRange(table, index, irs, null);
    assertEquals(keyRanges.size(), 1);
    Coprocessor.KeyRange keyRange = keyRanges.get(table.getId()).get(0);
    assertEquals(ByteString.copyFrom(new byte[] { 116, -128, 0, 0, 0, 0, 0, 0, 6, 95, 105, -128, 0, 0, 0, 0, 0, 0, 5, 3, -128, 0, 0, 0, 0, 0, 0, 0 }), keyRange.getStart());
    assertEquals(ByteString.copyFrom(new byte[] { 116, -128, 0, 0, 0, 0, 0, 0, 6, 95, 105, -128, 0, 0, 0, 0, 0, 0, 5, 3, -128, 0, 0, 0, 0, 0, 0, 1 }), keyRange.getEnd());
    exprs = ImmutableList.of(eq1, eq2);
    result = TiKVScanAnalyzer.extractConditions(exprs, table, index);
    irs = expressionToIndexRanges(result.getPointPredicates(), result.getRangePredicate(), table, index);
    keyRanges = scanAnalyzer.buildIndexScanKeyRange(table, index, irs, null);
    assertEquals(keyRanges.size(), 1);
    keyRange = keyRanges.get(table.getId()).get(0);
    assertEquals(ByteString.copyFrom(new byte[] { 116, -128, 0, 0, 0, 0, 0, 0, 6, 95, 105, -128, 0, 0, 0, 0, 0, 0, 5, 3, -128, 0, 0, 0, 0, 0, 0, 0, 0 }), keyRange.getStart());
    assertEquals(ByteString.copyFrom(new byte[] { 116, -128, 0, 0, 0, 0, 0, 0, 6, 95, 105, -128, 0, 0, 0, 0, 0, 0, 5, 3, -128, 0, 0, 0, 0, 0, 0, 0, 1, 119, 116, 102, 0, 0, 0, 0, 0, -5 }), keyRange.getEnd());
}
Also used : Coprocessor(org.tikv.kvproto.Coprocessor) Expression(com.pingcap.tikv.expression.Expression) TiTableInfo(com.pingcap.tikv.meta.TiTableInfo) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) TiIndexInfo(com.pingcap.tikv.meta.TiIndexInfo) Test(org.junit.Test)

Example 3 with TiIndexInfo

use of com.pingcap.tikv.meta.TiIndexInfo in project tispark by pingcap.

the class TiKVScanAnalyzerTest method extractConditionsWithPrimaryKeyTest.

@Test
public void extractConditionsWithPrimaryKeyTest() {
    TiTableInfo table = createTableWithPrefix();
    TiIndexInfo index = TiIndexInfo.generateFakePrimaryKeyIndex(table);
    requireNonNull(index);
    assertEquals(1, index.getIndexColumns().size());
    assertEquals("c1", index.getIndexColumns().get(0).getName());
    Expression eq1 = equal(ColumnRef.create("c1", table), Constant.create(0, IntegerType.INT));
    Expression eq2 = equal(ColumnRef.create("c2", table), Constant.create("test", StringType.VARCHAR));
    Expression le1 = lessEqual(ColumnRef.create("c3", table), Constant.create("fxxx", StringType.VARCHAR));
    // Last one should be pushed back
    Expression eq3 = equal(ColumnRef.create("c4", table), Constant.create("fxxx", StringType.VARCHAR));
    List<Expression> exprs = ImmutableList.of(eq1, eq2, le1, eq3);
    ScanSpec result = TiKVScanAnalyzer.extractConditions(exprs, table, index);
    Set<Expression> baselineSet = ImmutableSet.of(eq2, le1, eq3);
    // 3 remains since c2 condition pushed back as well
    assertEquals(baselineSet, result.getResidualPredicates());
    assertEquals(1, result.getPointPredicates().size());
    assertEquals(eq1, result.getPointPredicates().get(0));
    assertFalse(result.getRangePredicate().isPresent());
}
Also used : Expression(com.pingcap.tikv.expression.Expression) TiTableInfo(com.pingcap.tikv.meta.TiTableInfo) TiIndexInfo(com.pingcap.tikv.meta.TiIndexInfo) Test(org.junit.Test)

Example 4 with TiIndexInfo

use of com.pingcap.tikv.meta.TiIndexInfo in project tispark by pingcap.

the class TableCodecV2 method decodeRow.

protected static Row decodeRow(byte[] value, Handle handle, TiTableInfo tableInfo) {
    if (handle == null && tableInfo.isPkHandle()) {
        throw new IllegalArgumentException("when pk is handle, handle cannot be null");
    }
    int colSize = tableInfo.getColumns().size();
    // decode bytes to Map<ColumnID, Data>
    HashMap<Long, Object> decodedDataMap = new HashMap<>(colSize);
    RowV2 rowV2 = RowV2.createNew(value);
    TiIndexInfo pk = tableInfo.getPrimaryKey();
    if (pk != null) {
        List<TiColumnInfo> cols = new ArrayList<>();
        for (TiIndexColumn indexColumn : pk.getIndexColumns()) {
            TiColumnInfo col = tableInfo.getColumn(indexColumn.getOffset());
            cols.add(col);
        }
        if (tableInfo.isPkHandle()) {
            assert cols.size() == 1;
            decodedDataMap.put(cols.get(0).getId(), handle.data()[0]);
        }
        if (tableInfo.isCommonHandle()) {
            for (int i = 0; i < cols.size(); i++) {
                decodedDataMap.put(cols.get(i).getId(), handle.data()[i]);
            }
        }
    }
    for (TiColumnInfo col : tableInfo.getColumns()) {
        if (decodedDataMap.containsKey(col.getId())) {
            continue;
        } else if (col.isPrimaryKey() && tableInfo.isPkHandle()) {
            decodedDataMap.put(col.getId(), handle);
            continue;
        }
        RowV2.ColIDSearchResult searchResult = rowV2.findColID(col.getId());
        if (searchResult.isNull) {
            // current col is null, nothing should be added to decodedMap
            continue;
        }
        if (!searchResult.notFound) {
            // corresponding column should be found
            assert (searchResult.idx != -1);
            byte[] colData = rowV2.getData(searchResult.idx);
            Object d = RowDecoderV2.decodeCol(colData, col.getType());
            decodedDataMap.put(col.getId(), d);
        }
    }
    Object[] res = new Object[colSize];
    // construct Row with Map<ColumnID, Data> & handle
    for (int i = 0; i < colSize; i++) {
        // skip pk is handle case
        TiColumnInfo col = tableInfo.getColumn(i);
        res[i] = decodedDataMap.get(col.getId());
    }
    return ObjectRowImpl.create(res);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TiIndexColumn(com.pingcap.tikv.meta.TiIndexColumn) TiColumnInfo(com.pingcap.tikv.meta.TiColumnInfo) TiIndexInfo(com.pingcap.tikv.meta.TiIndexInfo)

Example 5 with TiIndexInfo

use of com.pingcap.tikv.meta.TiIndexInfo in project tispark by pingcap.

the class TiKVScanAnalyzer method isCoveringIndex.

// If all the columns requested in the select list of query, are available in the index, then the
// query engine doesn't have to lookup the table again compared with double read.
boolean isCoveringIndex(List<TiColumnInfo> columns, TiIndexInfo indexColumns, boolean pkIsHandle) {
    if (columns.isEmpty()) {
        return false;
    }
    Map<String, TiIndexColumn> colInIndex = indexColumns.getIndexColumns().stream().collect(Collectors.toMap(TiIndexColumn::getName, col -> col));
    for (TiColumnInfo colInfo : columns) {
        if (pkIsHandle && colInfo.isPrimaryKey()) {
            continue;
        }
        if (colInfo.getId() == -1) {
            continue;
        }
        boolean colNotInIndex = false;
        if (colInIndex.containsKey(colInfo.getName())) {
            TiIndexColumn indexCol = colInIndex.get(colInfo.getName());
            boolean isFullLength = indexCol.isLengthUnspecified() || indexCol.getLength() == colInfo.getType().getLength();
            if (!colInfo.getName().equalsIgnoreCase(indexCol.getName()) || !isFullLength) {
                colNotInIndex = true;
            }
        } else {
            colNotInIndex = true;
        }
        if (colNotInIndex) {
            return false;
        }
    }
    return true;
}
Also used : TiDAGRequest(com.pingcap.tikv.meta.TiDAGRequest) TableStatistics(com.pingcap.tikv.statistics.TableStatistics) EncodeType(com.pingcap.tidb.tipb.EncodeType) Expression(com.pingcap.tikv.expression.Expression) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) TiColumnInfo(com.pingcap.tikv.meta.TiColumnInfo) Key(com.pingcap.tikv.key.Key) IndexStatistics(com.pingcap.tikv.statistics.IndexStatistics) Pair(com.pingcap.tikv.util.Pair) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ImmutableList(com.google.common.collect.ImmutableList) TiPartitionDef(com.pingcap.tikv.meta.TiPartitionDef) Objects.requireNonNull(java.util.Objects.requireNonNull) Map(java.util.Map) TiClientInternalException(com.pingcap.tikv.exception.TiClientInternalException) PartitionPruner(com.pingcap.tikv.expression.PartitionPruner) TiIndexColumn(com.pingcap.tikv.meta.TiIndexColumn) TiTableInfo(com.pingcap.tikv.meta.TiTableInfo) Logger(org.slf4j.Logger) RowKey(com.pingcap.tikv.key.RowKey) TiIndexInfo(com.pingcap.tikv.meta.TiIndexInfo) Range(com.google.common.collect.Range) Set(java.util.Set) TiTimestamp(com.pingcap.tikv.meta.TiTimestamp) IndexMatcher(com.pingcap.tikv.expression.visitor.IndexMatcher) Collectors(java.util.stream.Collectors) KeyRangeUtils.makeCoprocRange(com.pingcap.tikv.util.KeyRangeUtils.makeCoprocRange) IndexScanKeyRangeBuilder(com.pingcap.tikv.key.IndexScanKeyRangeBuilder) TiStoreType(com.pingcap.tikv.region.TiStoreType) List(java.util.List) KeyRange(org.tikv.kvproto.Coprocessor.KeyRange) MySQLType(com.pingcap.tikv.types.MySQLType) PredicateUtils.expressionToIndexRanges(com.pingcap.tikv.predicates.PredicateUtils.expressionToIndexRanges) BoundType(com.google.common.collect.BoundType) IndexScanType(com.pingcap.tikv.meta.TiDAGRequest.IndexScanType) VisibleForTesting(com.google.common.annotations.VisibleForTesting) TypedKey(com.pingcap.tikv.key.TypedKey) TiIndexColumn(com.pingcap.tikv.meta.TiIndexColumn) TiColumnInfo(com.pingcap.tikv.meta.TiColumnInfo)

Aggregations

TiIndexInfo (com.pingcap.tikv.meta.TiIndexInfo)13 TiTableInfo (com.pingcap.tikv.meta.TiTableInfo)10 Test (org.junit.Test)10 Expression (com.pingcap.tikv.expression.Expression)9 ArrayList (java.util.ArrayList)6 TiIndexColumn (com.pingcap.tikv.meta.TiIndexColumn)5 ImmutableList (com.google.common.collect.ImmutableList)4 List (java.util.List)4 ColumnRef (com.pingcap.tikv.expression.ColumnRef)3 IndexMatcher (com.pingcap.tikv.expression.visitor.IndexMatcher)3 TiColumnInfo (com.pingcap.tikv.meta.TiColumnInfo)3 HashMap (java.util.HashMap)3 Range (com.google.common.collect.Range)2 ByteString (com.google.protobuf.ByteString)2 TiClientInternalException (com.pingcap.tikv.exception.TiClientInternalException)2 Constant (com.pingcap.tikv.expression.Constant)2 TypedKey (com.pingcap.tikv.key.TypedKey)2 TiStoreType (com.pingcap.tikv.region.TiStoreType)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1