From 0e2e70c4c18c064c90fc3341f1b4c99646c689df Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 14 Jun 2023 13:55:35 +0300 Subject: [PATCH] MDEV-31479: Inconsistency between MRR and SQL layer costs can cause poor query plan (Same as TODO-3938: best_access_path shows negative costs for mrr=on) best_access_path() assumes that quick select cost includes (quick->rows/TIME_FOR_COMPARE) as a cost of checking the attached part of the WHERE condition. It calls adjust_quick_cost() to subtract addition from quick's cost. The problem was that DS-MRR cost formula didn't include this cost. For very large tables, adjust_quick_cost() would produce a negative cost which would cause assert in debug build or bad query plan choice in release builds. Approved-by: Monty --- sql/multi_range_read.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc index c7c3079f28f..54a0340638c 100644 --- a/sql/multi_range_read.cc +++ b/sql/multi_range_read.cc @@ -2006,6 +2006,9 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, /* Total cost of all index accesses */ index_read_cost= primary_file->keyread_time(keynr, 1, rows); cost->add_io(index_read_cost, 1 /* Random seeks */); + + cost->cpu_cost+= (rows2double(rows) / TIME_FOR_COMPARE + + MULTI_RANGE_READ_SETUP_COST); return FALSE; }