You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-11-02 06:13:16 +03:00
feat: return bloat percentage in analyzePartitionBloat
This commit is contained in:
@@ -22,10 +22,12 @@
|
|||||||
*
|
*
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iomanip>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
#include "commandpackageprocessor.h"
|
#include "commandpackageprocessor.h"
|
||||||
@@ -475,6 +477,10 @@ DMLPackageProcessor::DMLResult CommandPackageProcessor::processPackageInternal(
|
|||||||
{
|
{
|
||||||
analyzePartitionBloat(cpackage, result);
|
analyzePartitionBloat(cpackage, result);
|
||||||
}
|
}
|
||||||
|
else if (stmt == "ANALYZETABLEBLOAT")
|
||||||
|
{
|
||||||
|
analyzeTableBloat(cpackage, result);
|
||||||
|
}
|
||||||
else if (!cpackage.get_Logging())
|
else if (!cpackage.get_Logging())
|
||||||
{
|
{
|
||||||
BRM::TxnID txnid = fSessionManager.getTxnID(cpackage.get_SessionID());
|
BRM::TxnID txnid = fSessionManager.getTxnID(cpackage.get_SessionID());
|
||||||
@@ -1195,7 +1201,7 @@ void CommandPackageProcessor::analyzePartitionBloat(const dmlpackage::CalpontDML
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SELECT COUNT(aux) AS count_aux FROM schema.table WHERE idbPartition(aux) = partitionStr;
|
// SELECT COUNT(aux) AS count_aux, COUNT(CASE aux WHEN 1 THEN 1 END) AS count_aux_deleted FROM schema.table WHERE idbPartition(aux) = partitionStr;
|
||||||
CalpontSelectExecutionPlan csep;
|
CalpontSelectExecutionPlan csep;
|
||||||
CalpontSelectExecutionPlan::ReturnedColumnList returnedColumnList;
|
CalpontSelectExecutionPlan::ReturnedColumnList returnedColumnList;
|
||||||
CalpontSelectExecutionPlan::FilterTokenList filterTokenList;
|
CalpontSelectExecutionPlan::FilterTokenList filterTokenList;
|
||||||
@@ -1223,16 +1229,74 @@ void CommandPackageProcessor::analyzePartitionBloat(const dmlpackage::CalpontDML
|
|||||||
SRCP auxSRCP(auxCol->clone());
|
SRCP auxSRCP(auxCol->clone());
|
||||||
countAuxCol->aggParms().push_back(auxSRCP);
|
countAuxCol->aggParms().push_back(auxSRCP);
|
||||||
|
|
||||||
|
// Create the CASE aux WHEN 1 THEN 1 END expression
|
||||||
|
FunctionColumn* caseCol = new FunctionColumn();
|
||||||
|
caseCol->functionName("case_simple"); // Use case_simple for expression comparison
|
||||||
|
caseCol->sessionID(fSessionID);
|
||||||
|
caseCol->expressionId(2);
|
||||||
|
caseCol->alias("case_aux_deleted");
|
||||||
|
|
||||||
|
// Set the result type for the CASE expression
|
||||||
|
CalpontSystemCatalog::ColType caseColType;
|
||||||
|
caseColType.colDataType = CalpontSystemCatalog::INT;
|
||||||
|
caseColType.colWidth = 4;
|
||||||
|
caseCol->resultType(caseColType);
|
||||||
|
|
||||||
|
// Create the WHEN value: 1
|
||||||
|
ConstantColumn* whenValue = new ConstantColumn("1", ConstantColumn::NUM);
|
||||||
|
whenValue->sessionID(fSessionID);
|
||||||
|
|
||||||
|
// Create the THEN result: 1
|
||||||
|
ConstantColumn* thenResult = new ConstantColumn("1", ConstantColumn::NUM);
|
||||||
|
thenResult->sessionID(fSessionID);
|
||||||
|
|
||||||
|
// Build the function parameters for CASE
|
||||||
|
funcexp::FunctionParm funcParms;
|
||||||
|
SPTP sptp;
|
||||||
|
|
||||||
|
// Add the CASE expression (aux column)
|
||||||
|
sptp.reset(new ParseTree(auxCol->clone()));
|
||||||
|
funcParms.push_back(sptp);
|
||||||
|
|
||||||
|
// Add the WHEN value
|
||||||
|
sptp.reset(new ParseTree(whenValue));
|
||||||
|
funcParms.push_back(sptp);
|
||||||
|
|
||||||
|
// Add the THEN result
|
||||||
|
sptp.reset(new ParseTree(thenResult));
|
||||||
|
funcParms.push_back(sptp);
|
||||||
|
|
||||||
|
// Set the function parameters
|
||||||
|
caseCol->functionParms(funcParms);
|
||||||
|
|
||||||
|
// Create the COUNT(CASE aux WHEN 1 THEN 1 END) AS count_aux_deleted aggregate column
|
||||||
|
AggregateColumn* countCaseCol = new AggregateColumn(fSessionID);
|
||||||
|
countCaseCol->alias("count_aux_deleted");
|
||||||
|
countCaseCol->aggOp(AggregateColumn::COUNT);
|
||||||
|
countCaseCol->functionName("count");
|
||||||
|
countCaseCol->expressionId(3);
|
||||||
|
CalpontSystemCatalog::ColType countCaseColType;
|
||||||
|
countCaseColType.colDataType = CalpontSystemCatalog::INT;
|
||||||
|
countCaseColType.colWidth = 4;
|
||||||
|
countCaseCol->resultType(countCaseColType);
|
||||||
|
|
||||||
|
SRCP caseSRCP(caseCol->clone());
|
||||||
|
countCaseCol->aggParms().push_back(caseSRCP);
|
||||||
|
|
||||||
// Add the base 'aux' column to ColumnMap (used for reference resolution)
|
// Add the base 'aux' column to ColumnMap (used for reference resolution)
|
||||||
// Note: The aggregate result "count_aux" does NOT go in ColumnMap
|
// Note: The aggregate results do NOT go in ColumnMap
|
||||||
// Add "aux" twice since it's referenced in both COUNT(aux) and idbPartition(aux)
|
// Add "aux" multiple times since it's referenced in COUNT(aux), CASE expression, and idbPartition(aux)
|
||||||
|
colMap.insert(CMVT_(tableName.schema + "." + tableName.table + "." + "aux", auxSRCP));
|
||||||
|
auxSRCP.reset(auxCol->clone());
|
||||||
colMap.insert(CMVT_(tableName.schema + "." + tableName.table + "." + "aux", auxSRCP));
|
colMap.insert(CMVT_(tableName.schema + "." + tableName.table + "." + "aux", auxSRCP));
|
||||||
auxSRCP.reset(auxCol->clone());
|
auxSRCP.reset(auxCol->clone());
|
||||||
colMap.insert(CMVT_(tableName.schema + "." + tableName.table + "." + "aux", auxSRCP));
|
colMap.insert(CMVT_(tableName.schema + "." + tableName.table + "." + "aux", auxSRCP));
|
||||||
|
|
||||||
// Add the COUNT column to ReturnedColumnList (what gets returned by SELECT)
|
// Add both COUNT columns to ReturnedColumnList (what gets returned by SELECT)
|
||||||
SRCP countSRCP(countAuxCol->clone());
|
SRCP countSRCP(countAuxCol->clone());
|
||||||
returnedColumnList.push_back(countSRCP);
|
returnedColumnList.push_back(countSRCP);
|
||||||
|
SRCP countCaseSRCP(countCaseCol->clone());
|
||||||
|
returnedColumnList.push_back(countCaseSRCP);
|
||||||
|
|
||||||
csep.columnMapNonStatic(colMap);
|
csep.columnMapNonStatic(colMap);
|
||||||
csep.returnedCols(returnedColumnList);
|
csep.returnedCols(returnedColumnList);
|
||||||
@@ -1242,23 +1306,23 @@ void CommandPackageProcessor::analyzePartitionBloat(const dmlpackage::CalpontDML
|
|||||||
|
|
||||||
// Create a FunctionColumn for idbPartition(aux)
|
// Create a FunctionColumn for idbPartition(aux)
|
||||||
// parms: psueducolumn dbroot, segmentdir, segment
|
// parms: psueducolumn dbroot, segmentdir, segment
|
||||||
SPTP sptp;
|
SPTP sptp2;
|
||||||
FunctionColumn* fc = new FunctionColumn();
|
FunctionColumn* fc = new FunctionColumn();
|
||||||
fc->functionName("idbpartition");
|
fc->functionName("idbpartition");
|
||||||
fc->sessionID(fSessionID);
|
fc->sessionID(fSessionID);
|
||||||
fc->expressionId(0);
|
fc->expressionId(0);
|
||||||
funcexp::FunctionParm parms;
|
funcexp::FunctionParm parms;
|
||||||
PseudoColumn* dbroot = new PseudoColumn(*auxCol, PSEUDO_DBROOT, fSessionID);
|
PseudoColumn* dbroot = new PseudoColumn(*auxCol, PSEUDO_DBROOT, fSessionID);
|
||||||
sptp.reset(new ParseTree(dbroot));
|
sptp2.reset(new ParseTree(dbroot));
|
||||||
parms.push_back(sptp);
|
parms.push_back(sptp2);
|
||||||
|
|
||||||
PseudoColumn* pp = new PseudoColumn(*auxCol, PSEUDO_SEGMENTDIR, fSessionID);
|
PseudoColumn* pp = new PseudoColumn(*auxCol, PSEUDO_SEGMENTDIR, fSessionID);
|
||||||
sptp.reset(new ParseTree(pp));
|
sptp2.reset(new ParseTree(pp));
|
||||||
parms.push_back(sptp);
|
parms.push_back(sptp2);
|
||||||
|
|
||||||
PseudoColumn* seg = new PseudoColumn(*auxCol, PSEUDO_SEGMENT, fSessionID);
|
PseudoColumn* seg = new PseudoColumn(*auxCol, PSEUDO_SEGMENT, fSessionID);
|
||||||
sptp.reset(new ParseTree(seg));
|
sptp2.reset(new ParseTree(seg));
|
||||||
parms.push_back(sptp);
|
parms.push_back(sptp2);
|
||||||
|
|
||||||
fc->functionParms(parms);
|
fc->functionParms(parms);
|
||||||
|
|
||||||
@@ -1295,26 +1359,23 @@ void CommandPackageProcessor::analyzePartitionBloat(const dmlpackage::CalpontDML
|
|||||||
csep.tableName(tableName.table, 0);
|
csep.tableName(tableName.table, 0);
|
||||||
|
|
||||||
// Send CSEP to ExeMgr
|
// Send CSEP to ExeMgr
|
||||||
auto csepStr = csep.toString();
|
|
||||||
cout << "csep: " << csepStr << endl;
|
|
||||||
CalpontSystemCatalog::NJLSysDataList sysDataList;
|
CalpontSystemCatalog::NJLSysDataList sysDataList;
|
||||||
systemCatalogPtr->getQueryData(csep, sysDataList);
|
systemCatalogPtr->getQueryData(csep, sysDataList);
|
||||||
|
|
||||||
cout << "Done getSysData" << endl;
|
int64_t countAux = 0;
|
||||||
|
int64_t countAuxDeleted = 0;
|
||||||
cout << "result size: " << sysDataList.sysDataVec.size() << endl;
|
|
||||||
|
|
||||||
// parse the result
|
|
||||||
for (auto it = sysDataList.begin(); it != sysDataList.end(); it++)
|
for (auto it = sysDataList.begin(); it != sysDataList.end(); it++)
|
||||||
{
|
{
|
||||||
cout << "result: " << (*it)->GetData(0) << endl;
|
if (it == sysDataList.begin()) {
|
||||||
|
countAux = (*it)->GetData(0);
|
||||||
|
} else {
|
||||||
|
countAuxDeleted = (*it)->GetData(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result - use toString() to get the full plan representation
|
analysisResults << std::fixed << std::setprecision(2) << (static_cast<double>(countAuxDeleted) / countAux) * 100 << "%";
|
||||||
analysisResults << sysDataList.sysDataVec.front()->GetData(0);
|
|
||||||
|
|
||||||
result.bloatAnalysis = analysisResults.str();
|
result.bloatAnalysis = analysisResults.str();
|
||||||
cout << "analysisResults: " << analysisResults.str() << endl;
|
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (std::exception& ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user