From f26063202e3ad7c58723d044d124f5d5e12461c7 Mon Sep 17 00:00:00 2001 From: "slzhou@taodata.com" Date: Mon, 11 Jul 2022 18:34:12 +0800 Subject: [PATCH] feat: tag scan optimization --- source/libs/planner/src/planOptimizer.c | 37 +++++++++++++++++-- source/libs/planner/test/planOptimizeTest.cpp | 7 ++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index d4c470be3c..2d57972fdd 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -1338,9 +1338,9 @@ static EDealRes partTagsOptHasColImpl(SNode* pNode, void* pContext) { return DEAL_RES_CONTINUE; } -static bool partTagsOptHasCol(SNodeList* pPartKeys) { +static bool planOptNodeListHasCol(SNodeList* pKeys) { bool hasCol = false; - nodesWalkExprs(pPartKeys, partTagsOptHasColImpl, &hasCol); + nodesWalkExprs(pKeys, partTagsOptHasColImpl, &hasCol); return hasCol; } @@ -1383,7 +1383,7 @@ static bool partTagsOptMayBeOptimized(SLogicNode* pNode) { return false; } - return !partTagsOptHasCol(partTagsGetPartKeys(pNode)) && partTagsOptAreSupportedFuncs(partTagsGetFuncs(pNode)); + return !planOptNodeListHasCol(partTagsGetPartKeys(pNode)) && partTagsOptAreSupportedFuncs(partTagsGetFuncs(pNode)); } static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) { @@ -2086,6 +2086,34 @@ static int32_t mergeProjectsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLog return mergeProjectsOptimizeImpl(pCxt, pLogicSubplan, pProjectNode); } +static bool tagScanMayBeOptimized(SLogicNode* pNode) { + if (QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(pNode) || (SCAN_TYPE_TAG == ((SScanLogicNode*)pNode)->scanType)) { + return false; + } + + if (NULL == pNode->pParent || QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode->pParent) || 1 != LIST_LENGTH(pNode->pParent->pChildren)) { + return false; + } + + SAggLogicNode* pAgg = (SAggLogicNode*)(pNode->pParent); + if (NULL == pAgg->pGroupKeys || NULL != pAgg->pAggFuncs || planOptNodeListHasCol(pAgg->pGroupKeys)) { + return false; + } + + return true; +} + +static int32_t tagScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) { + SScanLogicNode* pScanNode = (SScanLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, tagScanMayBeOptimized); + if (NULL == pScanNode) { + return TSDB_CODE_SUCCESS; + } + + pScanNode->scanType = SCAN_TYPE_TAG; + pCxt->optimized = true; + return TSDB_CODE_SUCCESS; +} + // clang-format off static const SOptimizeRule optimizeRuleSet[] = { {.pName = "ScanPath", .optimizeFunc = scanPathOptimize}, @@ -2098,7 +2126,8 @@ static const SOptimizeRule optimizeRuleSet[] = { {.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize}, {.pName = "RewriteTail", .optimizeFunc = rewriteTailOptimize}, {.pName = "RewriteUnique", .optimizeFunc = rewriteUniqueOptimize}, - {.pName = "LastRowScan", .optimizeFunc = lastRowScanOptimize} + {.pName = "LastRowScan", .optimizeFunc = lastRowScanOptimize}, + {.pName = "TagScan", .optimizeFunc = tagScanOptimize} }; // clang-format on diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp index e4019292d8..615a41d15d 100644 --- a/source/libs/planner/test/planOptimizeTest.cpp +++ b/source/libs/planner/test/planOptimizeTest.cpp @@ -85,4 +85,11 @@ TEST_F(PlanOptimizeTest, eliminateProjection) { TEST_F(PlanOptimizeTest, pushDownProjectCond) { useDb("root", "test"); run("select 1-abs(c1) from (select unique(c1) c1 from st1s3) where 1-c1>5 order by 1 nulls first"); +} + +TEST_F(PlanOptimizeTest, tagScan) { + useDb("root", "test"); + run("select tag1 from st1 group by tag1"); + run("select distinct tag1 from st1"); + run("select tag1*tag1 from st1 group by tag1*tag1"); } \ No newline at end of file -- GitLab