Repository navigation
TODO-6835 MVI and JSON: Optimizer fixes - #6025
mariadb-YuchenPei wants to merge 4 commits into
Conversation
get_claimed_key_part() appended clones at param->key_parts_end, so every later get_mm_parts() call iterated over them too and cloned each clone again. N independent predicates on the same RTREE/ARRAY field thus produced 2^(N-1) key parts, exhausting MAX_KEY at the 8th predicate (e.g. 8 ORed "x MEMBER OF (js)" lost range access). Keep clones in a separate region after key_parts_end, tracked by RANGE_OPT_PARAM::key_part_clones_end. get_mm_parts() only walks key_parts..key_parts_end, so each predicate creates at most one clone and N predicates use N key parts. Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
44bf6c0 to
6fd9997
Compare
6fd9997 to
3c3e6aa
Compare
9cc6ec2 to
71bfa1c
Compare
71bfa1c to
169ac2f
Compare
7373477 to
f7f154d
Compare
bade957 to
bce0ae1
Compare
Implemented get_mm_tree for JSON_OVERLAPS and JSON_CONTAINS. For each JSON_OVERLAPS/JSON_CONTAINS(field, value), parse the array or scalar element into a list. Map with get_mm_parts over the list and tree_or/tree_and the results. At leaf level uses a helper extracted from MEMBER OF. Also moved JSON_OVERLAPS to inherit from Item_bool_func2_with_rev due to its symmetry.
4c16f31 to
46ddba7
Compare
Before, every MEMBER OF / JSON_OVERLAPS / JSON_CONTAINS point got its
own cloned KEY_PART and key slot, and points were combined only through
index_merge (OR) or by picking one slot (AND).
Now all points on an ARRAY key part share the original slot:
* SEL_ARG_ARRAY holds a list of make_key() points ("the array contains
any of them") and the summed records_in_range() estimate and cost,
taken once when the point is built.
* key_or() of two ARRAY ranges takes the union of the points;
key_and() keeps the operand with the lower estimate, the WHERE
condition checks the rest.
* KEY_PART cloning (get_claimed_key_part()) is now RTREE-only, so
ARRAY-only queries size SEL_TREE::keys by param->keys again.
* QUICK_RANGE_SELECT_ARRAY gets one QUICK_RANGE per point and passes
all points to hlindex_read_first(); json_index reads them in turn
and skips trefs it has already returned.
* check_quick_select_array() uses the stored estimate, and rejects
non-ARRAY SEL_ARGs (e.g. IS NULL) on the ARRAY key part.
ORed MEMBER OF and JSON_OVERLAPS now give a single range scan instead
of index_merge sort_union, with no MAX_KEY limit on the number of
points.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
46ddba7 to
4bc6c49
Compare
|
The only piece of input to 2bf55f8 : I continue looking |
|
For: 3c3e6aa |
| */ | ||
| Json_range_elements json_get_range_elements(THD *thd, Item *value, | ||
| CHARSET_INFO *cs, | ||
| List<Item> *elements) |
There was a problem hiding this comment.
Does this need to be List or List<LEX_STRING> would suffice?
There was a problem hiding this comment.
As far as I understand, if you change this to be List<LEX_STRING> (or something else not using Item objects), then you won't need mem_root juggling in json_get_func_mm_tree():
MEM_ROOT *tmp_root= param->mem_root;
param->thd->mem_root= param->old_root;
Json_range_elements jre=
json_get_range_elements(param->thd, value, field->charset(), &elements);
param->thd->mem_root= tmp_root;There was a problem hiding this comment.
Another argument for not using Item objects:
"Range checked for each record" plans can call range optimizer O(#examined records) times. If MVI index is one among the considered, this could cause O(#examined records) Item objects to be allocated...
| template <class Get_mm_parts_func> | ||
| static SEL_TREE *json_get_func_mm_tree(RANGE_OPT_PARAM *param, Field *field, | ||
| Item *value, bool conjunctive, | ||
| Get_mm_parts_func &&get_mm_parts) |
There was a problem hiding this comment.
What was the goal to make this a template and then use Get_mm_parts_func &&get_mm_parts reference? Was it to get "perfect forwarding"? And if yes, why that was needed?
| if (je.state != JST_VALUE || json_read_value(&je)) | ||
| return Json_range_elements::NO_RANGE; | ||
| } | ||
| /* TODO: nested array and object fail the check here? */ |
There was a problem hiding this comment.
Yes, checked that this happens here.
This is based on #5841 .