You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-01 06:46:55 +03:00
feat(optimizer): temporary shield optimizer with a session variable
This commit is contained in:
@ -206,59 +206,58 @@ void CalpontSelectExecutionPlan::printSubCSEP(const size_t& ident, ostringstream
|
||||
{
|
||||
if (plan)
|
||||
{
|
||||
output << endlWithIndent(ident) << "{" << endlWithIndent(ident + 2) << plan->toString(ident + 2);
|
||||
// remove last two spaces from the stream.
|
||||
output.seekp(-2, std::ios::cur);
|
||||
output << "}" << std::endl << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << "{";
|
||||
output << plan->toString(ident + 2);
|
||||
output << endlWithIndent(ident) << "}";
|
||||
}
|
||||
}
|
||||
string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
||||
{
|
||||
ostringstream output;
|
||||
|
||||
output << "SELECT ";
|
||||
output << endlWithIndent(ident) << "SELECT ";
|
||||
|
||||
if (distinct())
|
||||
{
|
||||
output << "DISTINCT ";
|
||||
output << endlWithIndent(ident) << "DISTINCT ";
|
||||
}
|
||||
|
||||
output << "limit: " << limitStart() << " - " << limitNum() << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << "limit: " << limitStart() << " - " << limitNum();
|
||||
|
||||
switch (location())
|
||||
{
|
||||
case CalpontSelectExecutionPlan::MAIN: output << "MAIN" << endlWithIndent(ident); break;
|
||||
case CalpontSelectExecutionPlan::MAIN: output << endlWithIndent(ident) << "MAIN"; break;
|
||||
|
||||
case CalpontSelectExecutionPlan::FROM: output << "FROM" << endlWithIndent(ident); break;
|
||||
case CalpontSelectExecutionPlan::FROM: output << endlWithIndent(ident) << "FROM"; break;
|
||||
|
||||
case CalpontSelectExecutionPlan::WHERE: output << "WHERE" << endlWithIndent(ident); break;
|
||||
case CalpontSelectExecutionPlan::WHERE: output << endlWithIndent(ident) << "WHERE"; break;
|
||||
|
||||
case CalpontSelectExecutionPlan::HAVING: output << "HAVING" << endlWithIndent(ident); break;
|
||||
}
|
||||
|
||||
// Returned Column
|
||||
CalpontSelectExecutionPlan::ReturnedColumnList retCols = returnedCols();
|
||||
output << ">>Returned Columns" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << ">>Returned Columns";
|
||||
|
||||
uint32_t seq = 0;
|
||||
|
||||
for (unsigned int i = 0; i < retCols.size(); i++)
|
||||
{
|
||||
output << *retCols[i] << endlWithIndent(ident+2); // WIP replace with constant
|
||||
output << endlWithIndent(ident+2) << *retCols[i]; // WIP replace with constant
|
||||
|
||||
if (retCols[i]->colSource() & SELECT_SUB)
|
||||
{
|
||||
output << "select sub -- " << endlWithIndent(ident + 2);
|
||||
output << endlWithIndent(ident + 2) << "select sub -- ";
|
||||
CalpontSelectExecutionPlan* plan =
|
||||
dynamic_cast<CalpontSelectExecutionPlan*>(fSelectSubList[seq++].get());
|
||||
|
||||
printSubCSEP(ident, output, plan);
|
||||
printSubCSEP(ident + 2, output, plan);
|
||||
}
|
||||
}
|
||||
|
||||
// From Clause
|
||||
CalpontSelectExecutionPlan::TableList tables = tableList();
|
||||
output << ">>From Tables" << endlWithIndent(ident + 2);
|
||||
output << endlWithIndent(ident) <<">>From Tables";
|
||||
seq = 0;
|
||||
|
||||
for (unsigned int i = 0; i < tables.size(); i++)
|
||||
@ -266,28 +265,29 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
||||
// derived table
|
||||
if (tables[i].schema.length() == 0 && tables[i].table.length() == 0)
|
||||
{
|
||||
output << "derived table - " << tables[i].alias << endlWithIndent(ident+2);
|
||||
output << endlWithIndent(ident+2) << "derived table - " << tables[i].alias;
|
||||
CalpontSelectExecutionPlan* plan =
|
||||
dynamic_cast<CalpontSelectExecutionPlan*>(fDerivedTableList[seq++].get());
|
||||
|
||||
printSubCSEP(ident, output, plan);
|
||||
printSubCSEP(ident + 2, output, plan);
|
||||
}
|
||||
else
|
||||
{
|
||||
output << tables[i] << endlWithIndent(ident+2);
|
||||
output << endlWithIndent(ident+2) << tables[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Filters
|
||||
output << ">>Filters" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << ">>Filters";
|
||||
|
||||
if (filters() != nullptr)
|
||||
{
|
||||
output << endlWithIndent(ident + 2);
|
||||
filters()->walk(ParseTree::print, output);
|
||||
}
|
||||
else
|
||||
{
|
||||
output << "empty filter tree" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident + 2) << "empty filter tree";
|
||||
}
|
||||
|
||||
// Group by columns
|
||||
@ -295,12 +295,12 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
||||
|
||||
if (gbc.size() > 0)
|
||||
{
|
||||
output << ">>Group By Columns" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << ">>Group By Columns";
|
||||
output << std::string(ident, ' ');
|
||||
|
||||
for (unsigned int i = 0; i < gbc.size(); i++)
|
||||
{
|
||||
output << *gbc[i] << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident + 2) << *gbc[i];
|
||||
}
|
||||
output << std::string(ident, ' ');
|
||||
}
|
||||
@ -308,8 +308,7 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
||||
// Having
|
||||
if (having() != nullptr)
|
||||
{
|
||||
output << ">>Having" << endlWithIndent(ident);
|
||||
output << std::string(ident, ' ');
|
||||
output << endlWithIndent(ident) << ">>Having" << endlWithIndent(ident + 2);
|
||||
having()->walk(ParseTree::print, output);
|
||||
}
|
||||
|
||||
@ -318,33 +317,35 @@ string CalpontSelectExecutionPlan::toString(const size_t ident) const
|
||||
|
||||
if (obc.size() > 0)
|
||||
{
|
||||
output << ">>Order By Columns" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << ">>Order By Columns";
|
||||
|
||||
for (unsigned int i = 0; i < obc.size(); i++)
|
||||
output << *obc[i] << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident + 2) << *obc[i];
|
||||
}
|
||||
|
||||
output << "SessionID: " << fSessionID << endlWithIndent(ident);
|
||||
output << "TxnID: " << fTxnID << endlWithIndent(ident);
|
||||
output << "VerID: " << fVerID << endlWithIndent(ident);
|
||||
output << "TraceFlags: " << fTraceFlags << endlWithIndent(ident);
|
||||
output << "StatementID: " << fStatementID << endlWithIndent(ident);
|
||||
output << "DistUnionNum: " << (int)fDistinctUnionNum << endlWithIndent(ident);
|
||||
output << "Limit: " << fLimitStart << " - " << fLimitNum << endlWithIndent(ident);
|
||||
output << "String table threshold: " << fStringTableThreshold << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << "SessionID: " << fSessionID;
|
||||
output << endlWithIndent(ident) << "TxnID: " << fTxnID;
|
||||
output << endlWithIndent(ident) << "VerID: " << fVerID;
|
||||
output << endlWithIndent(ident) << "TraceFlags: " << fTraceFlags;
|
||||
output << endlWithIndent(ident) << "StatementID: " << fStatementID;
|
||||
output << endlWithIndent(ident) << "DistUnionNum: " << (int)fDistinctUnionNum;
|
||||
output << endlWithIndent(ident) << "Limit: " << fLimitStart << " - " << fLimitNum;
|
||||
output << endlWithIndent(ident) << "String table threshold: " << fStringTableThreshold;
|
||||
|
||||
output << "--- Column Map ---" << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << "--- Column Map ---";
|
||||
CalpontSelectExecutionPlan::ColumnMap::const_iterator iter;
|
||||
|
||||
for (iter = columnMap().begin(); iter != columnMap().end(); iter++)
|
||||
output << (*iter).first << " : " << (*iter).second << endlWithIndent(ident);
|
||||
{
|
||||
output << endlWithIndent(ident + 2) << (*iter).first << " : " << (*iter).second;
|
||||
}
|
||||
|
||||
output << "UUID: " << fUuid << endlWithIndent(ident);
|
||||
output << "QueryType: " << queryType() << endlWithIndent(ident);
|
||||
output << endlWithIndent(ident) << "UUID: " << fUuid;
|
||||
output << endlWithIndent(ident) << "QueryType: " << queryType();
|
||||
|
||||
if (!unionVec().empty())
|
||||
{
|
||||
output << "--- Union Unit ---";
|
||||
output << endlWithIndent(ident) << "--- Union Unit ---";
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < unionVec().size(); i++)
|
||||
|
@ -9209,7 +9209,7 @@ int cs_get_derived_plan(ha_columnstore_derived_handler* handler, THD* /*thd*/, S
|
||||
}
|
||||
|
||||
|
||||
int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCSEP& csep, gp_walk_info& gwi,
|
||||
int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* thd, SCSEP& csep, gp_walk_info& gwi,
|
||||
bool isSelectLexUnit)
|
||||
{
|
||||
SELECT_LEX& select_lex = handler->select_lex ? *handler->select_lex : *handler->lex_unit->first_select();
|
||||
@ -9241,12 +9241,15 @@ int cs_get_select_plan(ha_columnstore_select_handler* handler, THD* /*thd*/, SCS
|
||||
// Derived table projection and filter optimization.
|
||||
derivedTableOptimization(&gwi, csep);
|
||||
|
||||
bool csepWasOptimized = optimizer::optimizeCSEP(*csep);
|
||||
if (csep->traceOn() && csepWasOptimized)
|
||||
if (get_unstable_optimizer(thd))
|
||||
{
|
||||
cerr << "---------------- cs_get_select_plan optimized EXECUTION PLAN ----------------" << endl;
|
||||
cerr << *csep << endl;
|
||||
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
||||
bool csepWasOptimized = optimizer::optimizeCSEP(*csep);
|
||||
if (csep->traceOn() && csepWasOptimized)
|
||||
{
|
||||
cerr << "---------------- cs_get_select_plan optimized EXECUTION PLAN ----------------" << endl;
|
||||
cerr << *csep << endl;
|
||||
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -269,6 +269,7 @@ st_mysql_sys_var* mcs_system_variables[] = {
|
||||
MYSQL_SYSVAR(pron),
|
||||
MYSQL_SYSVAR(max_allowed_in_values),
|
||||
MYSQL_SYSVAR(innodb_queries_use_mcs),
|
||||
MYSQL_SYSVAR(unstable_optimizer),
|
||||
NULL};
|
||||
|
||||
st_mysql_show_var mcs_status_variables[] = {{"columnstore_version", (char*)&cs_version, SHOW_CHAR},
|
||||
|
@ -175,4 +175,7 @@ const char* get_pron(THD* thd);
|
||||
void set_pron(THD* thd, char* value);
|
||||
|
||||
ulong get_max_allowed_in_values(THD* thd);
|
||||
void set_max_allowed_in_values(THD* thd, ulong value);
|
||||
void set_max_allowed_in_values(THD* thd, ulong value);
|
||||
|
||||
bool get_unstable_optimizer(THD* thd);
|
||||
void set_unstable_optimizer(THD* thd, bool value);
|
||||
|
@ -110,7 +110,7 @@ bool tableIsInUnion(const execplan::CalpontSystemCatalog::TableAliasName& table,
|
||||
bool matchParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
||||
{
|
||||
auto tables = csep.tableList();
|
||||
// This is leaf and there are no other tables at this level.
|
||||
// This is leaf and there are no other tables at this level in neither UNION, nor derived table.
|
||||
// WIP filter out CSEPs with orderBy, groupBy, having
|
||||
// WIP filter out CSEPs with nonSimpleColumns in projection
|
||||
return tables.size() == 1 && !tables[0].isColumnstore() && !tableIsInUnion(tables[0], csep);
|
||||
@ -142,13 +142,14 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
||||
if (!table.isColumnstore())
|
||||
{
|
||||
auto derivedSCEP = csep.cloneWORecursiveSelects();
|
||||
// need to intro a level
|
||||
// need to add a level here
|
||||
std::string alias = aliasPrefix + table.schema + "_" + table.table;
|
||||
|
||||
derivedSCEP->location(execplan::CalpontSelectExecutionPlan::FROM);
|
||||
derivedSCEP->subType(execplan::CalpontSelectExecutionPlan::FROM_SUBS);
|
||||
derivedSCEP->derivedTbAlias(alias);
|
||||
|
||||
// TODO: hardcoded for now
|
||||
size_t parallelFactor = 2;
|
||||
auto additionalUnionVec = makeUnionFromTable(parallelFactor, csep);
|
||||
derivedSCEP->unionVec().insert(derivedSCEP->unionVec().end(), additionalUnionVec.begin(), additionalUnionVec.end());
|
||||
@ -166,23 +167,15 @@ void applyParallelCES(execplan::CalpontSelectExecutionPlan& csep)
|
||||
}
|
||||
}
|
||||
|
||||
// WIP need to work with existing derived tables
|
||||
newDerivedTableList.push_back(derivedSCEP);
|
||||
// WIP
|
||||
execplan::CalpontSystemCatalog::TableAliasName tn = execplan::make_aliasview("", "", alias, "");
|
||||
newTableList.push_back(tn);
|
||||
}
|
||||
}
|
||||
|
||||
// SimpleColumn* sc = new SimpleColumn("test", "i1", "i", false, csep.sessionID());
|
||||
// string alias(table->alias.c_ptr());
|
||||
// sc->timeZone(csep.timeZone());
|
||||
// sc->partitions(getPartitions(table));
|
||||
// boost::shared_ptr<SimpleColumn> spsc(sc);
|
||||
|
||||
// csep.columnMap().insert({"`test`.`i1`.`i`", spsc});
|
||||
|
||||
// There must be no derived at this point.
|
||||
csep.derivedTableList(newDerivedTableList);
|
||||
// Replace table list with new table list populated with union units
|
||||
csep.tableList(newTableList);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user