![]() |
MySQL 8.0.32
Source Code Documentation
|
join cache optimizations More...
#include "sql/sql_join_buffer.h"
#include <assert.h>
#include <limits.h>
#include <sys/types.h>
#include <unordered_map>
#include "my_alloc.h"
#include "my_bitmap.h"
#include "sql/field.h"
#include "sql/sql_bitmap.h"
#include "sql/sql_const.h"
#include "sql/sql_executor.h"
#include "sql/table.h"
Functions | |
static void | filter_gcol_for_dynamic_range_scan (const QEP_TAB *tab) |
Filter base columns of virtual generated columns that might not be read by a dynamic range scan. More... | |
void | filter_virtual_gcol_base_cols (const QEP_TAB *qep_tab) |
Filter the base columns of virtual generated columns if using a covering index scan. More... | |
void | add_virtual_gcol_base_cols (TABLE *table, MEM_ROOT *mem_root, MY_BITMAP *completed_read_set) |
Create a read set that undoes the work of filter_virtual_gcol_base_cols(); ie., for every virtual generated column that is part of the given table's read set, we also include the base tables. More... | |
join cache optimizations
void add_virtual_gcol_base_cols | ( | TABLE * | table, |
MEM_ROOT * | mem_root, | ||
MY_BITMAP * | completed_read_set | ||
) |
Create a read set that undoes the work of filter_virtual_gcol_base_cols(); ie., for every virtual generated column that is part of the given table's read set, we also include the base tables.
This is needed if we revert from a covering index back to a table scan (which doesn't store the virtual generated columns themselves, unlike the covering index). This happens in DynamicRangeIterator and AlternativeIterator.
The new read set gets a new buffer, allocated on the given MEM_ROOT. table->read_set is not changed.
|
static |
Filter base columns of virtual generated columns that might not be read by a dynamic range scan.
A dynamic range scan will read the data from a table using either a table scan, a range scan on a covering index, or a range scan on a non-covering index. The table's read set contains all columns that will be read by the table scan. This might be base columns that are used to evaluate virtual column values that are part of an index. When the table is read using a table scan, these base columns will be read from the storage engine, but when a index/range scan on a covering index is used, the base columns will not be read by the storage engine. To avoid that these potentially un-read columns are inserted into the join buffer, we need to adjust the read set to only contain columns that are read independently of which access method that is used: these are the only columns needed in the join buffer for the query.
This function does the following manipulations of table's read_set:
if one or more of the alternative range scan indexes are covering, then the table's read_set is intersected with the read_set for each of the covering indexes.
For potential range indexes that are not covering, no adjustment to the read_set is done.
tab | the query execution tab |
void filter_virtual_gcol_base_cols | ( | const QEP_TAB * | qep_tab | ) |
Filter the base columns of virtual generated columns if using a covering index scan.
Adjust table->read_set so that it only contains the columns that are needed in the join operation and afterwards.
For a virtual generated column, all base columns are added to the read_set of the table. The storage engine will then copy all base column values so that the value of the GC can be calculated inside the executor. But when a virtual GC is fetched using a covering index, the actual GC value is fetched by the storage engine and the base column values are not needed. Code that looks at the read sets (join buffering, hash join, filesort) must not try to copy them. So, we eliminate from read_set those columns that are available from the covering index.
Note that some iterators (DynamicRangeIterator and AlternativeIterator) may need to switch back to table scans. If so, they will adjust the table's read set before reading; see add_virtual_gcol_base_cols().