Details
-
Task
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
Description
Solution 1 overview:
This is a basic solution where we use one page number range for all the intervals that are scanned:
check_quick_select()
|
{
|
// We're considering range access on some index |
ha_innobase::multi_range_info_const()
|
{
|
dsmrr_info_const()
|
{
|
for each range { |
// this returns page rage for this interval. |
ha_innobase::record_in_range(&page_range);
|
|
|
// build one single page range that covers |
// all intervals we'll scan. |
}
|
// return the page range. |
}
|
// return page range. |
}
|
|
|
// Save the page range (denote $PR) that covers all intervals. |
// We'll use it in the range. |
}
|
QUICK_RANGE_SELECT::reset()
|
{
|
// Provide saved $PR to the storage engine. |
file->advise_page_range(&mrr_pages_range);
|
file->multi_range_read_init(...);
|
}
|
class ha_innobase { |
...
|
page_range m_scanned_page_range;
|
|
|
|
|
// inform the storage engine that we're going to read pages in this range. |
// UNUSED_PAGE_NO means "no information". |
void advise_page_range(page_range *); |
|
int reset() override { |
m_scanned_page_range = { UNUSED_PAGE_NO, UNUSED_PAGE_NO};
|
}
|
}
|
Testcase
create table t2 (a int, b int, index(a), index(b));
|
insert into t2 select seq, seq from seq_1_to_10000;
|
|
|
analyze
|
select * from t2 where a in (10, 1000, 2000) and b between 200 and 300;
|
Testcase output: the server stderr shows the calls SQL layer was making:
records_in_range(
|
index=a
|
page_range={42949672969, 42949672969}
|
)
|
records_in_range(
|
index=a
|
page_range={42949672970, 42949672970}
|
)
|
records_in_range(
|
index=a
|
page_range={42949672974, 42949672974}
|
)
|
range estimation(index=a):
|
page_range={42949672969, 42949672974}
|
)
|
records_in_range(
|
index=b
|
page_range={42949672971, 42949672971}
|
)
|
range estimation(index=b):
|
page_range={42949672971, 42949672971}
|
)
|
and now ha_innobase::multi_range_read_init can see which ranges we're about to scan:
ha_innobase::multi_range_read_init(
|
active_index=a
|
m_scanned_page_range={42949672969, 42949672974}
|
)
|