| 253 | } |
| 254 | |
| 255 | std::pair<PlanSegmentTreePtr, std::set<StorageID>> InterpreterSelectQueryUseOptimizer::getPlanSegment() |
| 256 | { |
| 257 | Stopwatch stage_watch, total_watch; |
| 258 | total_watch.start(); |
| 259 | setUnsupportedSettings(context); |
| 260 | QueryPlanPtr query_plan = getQueryPlan(); |
| 261 | |
| 262 | query_plan->setResetStepId(false); |
| 263 | stage_watch.start(); |
| 264 | QueryPlan plan = PlanNodeToNodeVisitor::convert(*query_plan); |
| 265 | |
| 266 | LOG_DEBUG(log, "optimizer stage run time: plan normalize, {} ms", stage_watch.elapsedMillisecondsAsDouble()); |
| 267 | stage_watch.restart(); |
| 268 | |
| 269 | PlanSegmentTreePtr plan_segment_tree = std::make_unique<PlanSegmentTree>(); |
| 270 | ClusterInfoContext cluster_info_context{.query_plan = *query_plan, .context = context, .plan_segment_tree = plan_segment_tree}; |
| 271 | PlanSegmentContext plan_segment_context = ClusterInfoFinder::find(*query_plan, cluster_info_context); |
| 272 | |
| 273 | stage_watch.restart(); |
| 274 | std::set<StorageID> used_storage_ids = plan.allocateLocalTable(context); |
| 275 | |
| 276 | blockQueryJSONUseOptimizer(used_storage_ids, context); |
| 277 | // select health worker before split |
| 278 | if (context->getSettingsRef().enable_adaptive_scheduler && context->tryGetCurrentWorkerGroup()) |
| 279 | { |
| 280 | context->selectWorkerNodesWithMetrics(); |
| 281 | auto wg_health = context->getWorkerGroupStatusPtr()->getWorkerGroupHealth(); |
| 282 | if (wg_health == WorkerGroupHealthStatus::Critical) |
| 283 | throw Exception("no worker available", ErrorCodes::LOGICAL_ERROR); |
| 284 | } |
| 285 | |
| 286 | PlanSegmentSplitter::split(plan, plan_segment_context); |
| 287 | context->logOptimizerProfile( |
| 288 | log, "Optimizer total run time: ", "PlanSegment build", std::to_string(stage_watch.elapsedMillisecondsAsDouble()) + "ms"); |
| 289 | ProfileEvents::increment(ProfileEvents::PlanSegmentSplitterTime, stage_watch.elapsedMilliseconds()); |
| 290 | |
| 291 | resetFinalSampleSize(plan_segment_tree); |
| 292 | setPlanSegmentInfoForExplainAnalyze(plan_segment_tree); |
| 293 | GraphvizPrinter::printPlanSegment(plan_segment_tree, context); |
| 294 | context->logOptimizerProfile( |
| 295 | log, "Optimizer total run time: ", "Optimizer Total", std::to_string(total_watch.elapsedMillisecondsAsDouble()) + "ms"); |
| 296 | |
| 297 | if (context->getSettingsRef().log_segment_profiles) |
| 298 | { |
| 299 | segment_profiles = std::make_shared<std::vector<String>>(); |
| 300 | for (auto & node : plan_segment_tree->getNodes()) |
| 301 | segment_profiles->emplace_back(PlanSegmentDescription::getPlanSegmentDescription(node.plan_segment, true)->jsonPlanSegmentDescriptionAsString({})); |
| 302 | } |
| 303 | |
| 304 | return std::make_pair(std::move(plan_segment_tree), std::move(used_storage_ids)); |
| 305 | } |
| 306 | |
| 307 | QueryPipeline executeTEALimit(QueryPipeline & pipeline, ContextMutablePtr context, ASTPtr query_ptr, Poco::Logger * log) |
| 308 | { |
no test coverage detected