enh: optimize stable tbname equal query

This commit is contained in:
dapan1121 2024-08-29 16:29:51 +08:00
parent 99102d47ac
commit 39189c9e62
3 changed files with 87 additions and 7 deletions

View File

@ -214,6 +214,7 @@ typedef struct SRealTableNode {
double ratio;
SArray* pSmaIndexes;
int8_t cacheLastMode;
int8_t stbRewrite;
SArray* pTsmas;
SArray* tsmaTargetTbVgInfo; // SArray<SVgroupsInfo*>, used for child table or normal table only
SArray* tsmaTargetTbInfo; // SArray<STsmaTargetTbInfo>, used for child table or normal table only

View File

@ -107,6 +107,7 @@ typedef struct SCollectMetaKeyCxt {
typedef struct SCollectMetaKeyFromExprCxt {
SCollectMetaKeyCxt* pComCxt;
bool hasLastRowOrLast;
bool tbnameCollect;
int32_t errCode;
} SCollectMetaKeyFromExprCxt;
@ -204,6 +205,45 @@ static EDealRes collectMetaKeyFromTempTable(SCollectMetaKeyFromExprCxt* pCxt, ST
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
}
static int32_t isTbnameEqCondOperator(SOperatorNode* pOperator, char** ppTableName) {
if (pOperator->opType != OP_TYPE_EQUAL) {
return TSDB_CODE_SUCCESS;
}
SValueNode* pValueNode = NULL;
if (nodeType(pOperator->pLeft) == QUERY_NODE_FUNCTION &&
0 == strcasecmp(((SFunctionNode*)(pOperator->pLeft))->functionName, "tbname") &&
nodeType(pOperator->pRight) == QUERY_NODE_VALUE) {
pValueNode = (SValueNode*)pOperator->pRight;
} else if (nodeType(pOperator->pRight) == QUERY_NODE_FUNCTION &&
0 == strcasecmp(((SFunctionNode*)(pOperator->pRight))->functionName, "tbname") &&
nodeType(pOperator->pLeft) == QUERY_NODE_VALUE) {
pValueNode = (SValueNode*)pOperator->pLeft;
} else {
return TSDB_CODE_SUCCESS;
}
*ppTableName = pValueNode->literal;
return TSDB_CODE_SUCCESS;
}
static EDealRes collectMetaKeyFromOperator(SCollectMetaKeyFromExprCxt* pCxt, SOperatorNode* pOpNode) {
if (!pCxt->tbnameCollect) {
return DEAL_RES_CONTINUE;
}
char* pTableName = NULL;
int32_t code = isTbnameEqCondOperator((SOperatorNode*)pOpNode, &pTableName);
if (TSDB_CODE_SUCCESS != code) return DEAL_RES_CONTINUE;
if (pTableName) {
SSelectStmt* pSelect = (SSelectStmt*)pCxt->pComCxt->pStmt;
pCxt->errCode = collectMetaKeyFromRealTableImpl(pCxt->pComCxt, ((SRealTableNode*)pSelect->pFromTable)->table.dbName, pTableName, AUTH_TYPE_READ);
}
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
}
static EDealRes collectMetaKeyFromExprImpl(SNode* pNode, void* pContext) {
SCollectMetaKeyFromExprCxt* pCxt = pContext;
switch (nodeType(pNode)) {
@ -213,6 +253,8 @@ static EDealRes collectMetaKeyFromExprImpl(SNode* pNode, void* pContext) {
return collectMetaKeyFromRealTable(pCxt, (SRealTableNode*)pNode);
case QUERY_NODE_TEMP_TABLE:
return collectMetaKeyFromTempTable(pCxt, (STempTableNode*)pNode);
case QUERY_NODE_OPERATOR:
return collectMetaKeyFromOperator(pCxt, (SOperatorNode*)pNode);
default:
break;
}
@ -220,7 +262,7 @@ static EDealRes collectMetaKeyFromExprImpl(SNode* pNode, void* pContext) {
}
static int32_t collectMetaKeyFromExprs(SCollectMetaKeyCxt* pCxt, SNodeList* pList) {
SCollectMetaKeyFromExprCxt cxt = {.pComCxt = pCxt, .errCode = TSDB_CODE_SUCCESS};
SCollectMetaKeyFromExprCxt cxt = {.pComCxt = pCxt, .errCode = TSDB_CODE_SUCCESS, .tbnameCollect = false};
nodesWalkExprs(pList, collectMetaKeyFromExprImpl, &cxt);
return cxt.errCode;
}
@ -245,6 +287,9 @@ static int32_t reserveDbCfgForLastRow(SCollectMetaKeyCxt* pCxt, SNode* pTable) {
static int32_t collectMetaKeyFromSelect(SCollectMetaKeyCxt* pCxt, SSelectStmt* pStmt) {
SCollectMetaKeyFromExprCxt cxt = {.pComCxt = pCxt, .hasLastRowOrLast = false, .errCode = TSDB_CODE_SUCCESS};
if (pStmt->pFromTable && QUERY_NODE_REAL_TABLE == nodeType(pStmt->pFromTable)) {
cxt.tbnameCollect = true;
}
nodesWalkSelectStmt(pStmt, SQL_CLAUSE_FROM, collectMetaKeyFromExprImpl, &cxt);
if (TSDB_CODE_SUCCESS == cxt.errCode && cxt.hasLastRowOrLast) {
cxt.errCode = reserveDbCfgForLastRow(pCxt, pStmt->pFromTable);

View File

@ -1275,7 +1275,7 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p
if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) {
const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta;
int32_t nums = pMeta->tableInfo.numOfColumns +
(igTags ? 0 : ((TSDB_SUPER_TABLE == pMeta->tableType) ? pMeta->tableInfo.numOfTags : 0));
(igTags ? 0 : ((TSDB_SUPER_TABLE == pMeta->tableType || ((SRealTableNode*)pTable)->stbRewrite) ? pMeta->tableInfo.numOfTags : 0));
for (int32_t i = 0; i < nums; ++i) {
if (invisibleColumn(pCxt->pParseCxt->enableSysInfo, pMeta->tableType, pMeta->schema[i].flags)) {
pCxt->pParseCxt->hasInvisibleCol = true;
@ -5964,6 +5964,7 @@ static int32_t isOperatorEqTbnameCond(STranslateContext* pCxt, SOperatorNode* pO
*pRet = false;
return TSDB_CODE_SUCCESS;
}
SFunctionNode* pTbnameFunc = NULL;
SValueNode* pValueNode = NULL;
if (nodeType(pOperator->pLeft) == QUERY_NODE_FUNCTION &&
@ -6041,7 +6042,6 @@ static int32_t isOperatorTbnameInCond(STranslateContext* pCxt, SOperatorNode* pO
static int32_t findEqCondTbNameInOperatorNode(STranslateContext* pCxt, SNode* pWhere, SEqCondTbNameTableInfo* pInfo, bool* pRet) {
int32_t code = TSDB_CODE_SUCCESS;
char* pTableAlias = NULL;
char* pTbNameVal = NULL;
bool eqTbnameCond = false, tbnameInCond = false;
code = isOperatorEqTbnameCond(pCxt, (SOperatorNode*)pWhere, &pTableAlias, &pInfo->aTbnames, &eqTbnameCond);
if (TSDB_CODE_SUCCESS == code) {
@ -6222,12 +6222,40 @@ static void findVgroupsFromEqualTbname(STranslateContext* pCxt, SArray* aTbnames
}
}
static int32_t replaceToChildTableQuery(STranslateContext* pCxt, SEqCondTbNameTableInfo* pInfo) {
SName snameTb;
char* tbName = taosArrayGetP(pInfo->aTbnames, 0);
(void)toName(pCxt->pParseCxt->acctId, pInfo->pRealTable->table.dbName, tbName, &snameTb);
STableMeta* pMeta = NULL;
TAOS_CHECK_RETURN(catalogGetCachedTableMeta(pCxt->pParseCxt->pCatalog, &snameTb, &pMeta));
if (NULL == pMeta || TSDB_CHILD_TABLE != pMeta->tableType || pMeta->suid != pInfo->pRealTable->pMeta->suid) {
goto _return;
}
pInfo->pRealTable->pMeta->uid = pMeta->uid;
pInfo->pRealTable->pMeta->vgId = pMeta->vgId;
pInfo->pRealTable->pMeta->tableType = pMeta->tableType;
tstrncpy(pInfo->pRealTable->table.tableName, tbName, sizeof(pInfo->pRealTable->table.tableName));
pInfo->pRealTable->stbRewrite = true;
_return:
taosMemoryFree(pMeta);
return TSDB_CODE_SUCCESS;
}
static int32_t setEqualTbnameTableVgroups(STranslateContext* pCxt, SSelectStmt* pSelect, SArray* aTables) {
int32_t code = TSDB_CODE_SUCCESS;
for (int i = 0; i < taosArrayGetSize(aTables); ++i) {
SEqCondTbNameTableInfo* pInfo = taosArrayGet(aTables, i);
int32_t nTbls = taosArrayGetSize(pInfo->aTbnames);
int32_t aTableNum = taosArrayGetSize(aTables);
int32_t nTbls = 0;
bool stableQuery = false;
SEqCondTbNameTableInfo* pInfo = NULL;
for (int i = 0; i < aTableNum; ++i) {
pInfo = taosArrayGet(aTables, i);
int32_t numOfVgs = pInfo->pRealTable->pVgroupList->numOfVgroups;
nTbls = taosArrayGetSize(pInfo->aTbnames);
SVgroupsInfo* vgsInfo = taosMemoryMalloc(sizeof(SVgroupsInfo) + nTbls * sizeof(SVgroupInfo));
findVgroupsFromEqualTbname(pCxt, pInfo->aTbnames, pInfo->pRealTable->table.dbName, numOfVgs, vgsInfo);
@ -6237,6 +6265,7 @@ static int32_t setEqualTbnameTableVgroups(STranslateContext* pCxt, SSelectStmt*
} else {
taosMemoryFree(vgsInfo);
}
stableQuery = pInfo->pRealTable->pMeta->tableType == TSDB_SUPER_TABLE;
vgsInfo = NULL;
if (pInfo->pRealTable->pTsmas) {
@ -6276,7 +6305,12 @@ static int32_t setEqualTbnameTableVgroups(STranslateContext* pCxt, SSelectStmt*
}
}
}
return TSDB_CODE_SUCCESS;
if (TSDB_CODE_SUCCESS == code && 1 == aTableNum && 1 == nTbls && stableQuery) {
code = replaceToChildTableQuery(pCxt, pInfo);
}
return code;
}
static int32_t setTableVgroupsFromEqualTbnameCond(STranslateContext* pCxt, SSelectStmt* pSelect) {