543
543
static int fill_used_fields_bitmap(optimizer::Parameter *param)
545
545
Table *table= param->table;
548
param->tmp_covered_fields.setBitmap(0);
549
param->fields_bitmap_size= table->getShare()->column_bitmap_size;
550
if (!(tmp= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)) ||
551
param->needed_fields.init(tmp, table->getShare()->sizeFields()))
547
param->tmp_covered_fields.clear();
548
param->needed_fields.resize(table->getShare()->sizeFields());
549
param->needed_fields.reset();
556
param->needed_fields= *table->read_set;
557
bitmap_union(¶m->needed_fields, table->write_set);
551
param->needed_fields|= *table->read_set;
552
param->needed_fields|= *table->write_set;
559
554
pk= param->table->getShare()->getPrimaryKey();
560
555
if (pk != MAX_KEY && param->table->cursor->primary_key_is_clustered())
564
559
KeyPartInfo *key_part_end= key_part +
565
560
param->table->key_info[pk].key_parts;
566
561
for (;key_part != key_part_end; ++key_part)
567
param->needed_fields.clearBit(key_part->fieldnr-1);
562
param->needed_fields.reset(key_part->fieldnr-1);
1193
typedef struct st_ror_scan_info
1195
uint32_t idx; /* # of used key in param->keys */
1196
uint32_t keynr; /* # of used key in table */
1197
ha_rows records; /* estimate of # records this scan will return */
1199
/* Set of intervals over key fields that will be used for row retrieval. */
1200
optimizer::SEL_ARG *sel_arg;
1202
/* Fields used in the query and covered by this ROR scan. */
1203
MyBitmap covered_fields;
1204
uint32_t used_fields_covered; /* # of set bits in covered_fields */
1205
int key_rec_length; /* length of key record (including rowid) */
1208
Cost of reading all index records with values in sel_arg intervals set
1209
(assuming there is no need to access full table records)
1211
double index_read_cost;
1212
uint32_t first_uncovered_field; /* first unused bit in covered_fields */
1213
uint32_t key_components; /* # of parts in the key */
1218
Create ROR_SCAN_INFO* structure with a single ROR scan on index idx using
1190
Create optimizer::RorScanInfo* structure with a single ROR scan on index idx using
1219
1191
sel_arg set of intervals.
1233
ROR_SCAN_INFO *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1205
optimizer::RorScanInfo *make_ror_scan(const optimizer::Parameter *param, int idx, optimizer::SEL_ARG *sel_arg)
1235
ROR_SCAN_INFO *ror_scan;
1236
my_bitmap_map *bitmap_buf;
1207
optimizer::RorScanInfo *ror_scan= NULL;
1238
1209
uint32_t keynr;
1240
if (!(ror_scan= (ROR_SCAN_INFO*)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO))))
1211
if (!(ror_scan= (optimizer::RorScanInfo*)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo))))
1243
1214
ror_scan->idx= idx;
1247
1218
ror_scan->sel_arg= sel_arg;
1248
1219
ror_scan->records= param->table->quick_rows[keynr];
1250
if (!(bitmap_buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1255
if (ror_scan->covered_fields.init(bitmap_buf, param->table->getShare()->sizeFields()))
1259
ror_scan->covered_fields.clearAll();
1221
ror_scan->covered_fields_size= param->table->getShare()->sizeFields();
1222
boost::dynamic_bitset<> tmp_bitset(param->table->getShare()->sizeFields());
1261
1225
KeyPartInfo *key_part= param->table->key_info[keynr].key_part;
1262
1226
KeyPartInfo *key_part_end= key_part +
1263
1227
param->table->key_info[keynr].key_parts;
1264
for (;key_part != key_part_end; ++key_part)
1228
for (; key_part != key_part_end; ++key_part)
1266
if (param->needed_fields.isBitSet(key_part->fieldnr-1))
1267
ror_scan->covered_fields.setBit(key_part->fieldnr-1);
1230
if (param->needed_fields.test(key_part->fieldnr-1))
1231
tmp_bitset.set(key_part->fieldnr-1);
1269
1233
double rows= rows2double(param->table->quick_rows[ror_scan->keynr]);
1270
1234
ror_scan->index_read_cost=
1271
1235
param->table->cursor->index_only_read_time(ror_scan->keynr, rows);
1236
ror_scan->covered_fields= tmp_bitset.to_ulong();
1277
Compare two ROR_SCAN_INFO** by E(#records_matched) * key_record_length.
1242
Compare two optimizer::RorScanInfo** by E(#records_matched) * key_record_length.
1279
1244
cmp_ror_scan_info()
1280
1245
a ptr to first compared value
1289
static int cmp_ror_scan_info(ROR_SCAN_INFO** a, ROR_SCAN_INFO** b)
1254
static int cmp_ror_scan_info(optimizer::RorScanInfo** a, optimizer::RorScanInfo** b)
1291
1256
double val1= rows2double((*a)->records) * (*a)->key_rec_length;
1292
1257
double val2= rows2double((*b)->records) * (*b)->key_rec_length;
1331
1296
/* Auxiliary structure for incremental ROR-intersection creation */
1297
typedef struct st_ror_intersect_info
1299
st_ror_intersect_info()
1306
index_scan_costs(0.0),
1310
st_ror_intersect_info(const optimizer::Parameter *in_param)
1313
covered_fields(in_param->table->getShare()->sizeFields()),
1314
out_rows(in_param->table->cursor->stats.records),
1317
index_scan_costs(0.0),
1320
covered_fields.reset();
1334
1323
const optimizer::Parameter *param;
1335
MyBitmap covered_fields; /* union of fields covered by all scans */
1324
boost::dynamic_bitset<> covered_fields; /* union of fields covered by all scans */
1337
1326
Fraction of table records that satisfies conditions of all scans.
1338
1327
This is the number of full records that will be retrieved if a
1348
1337
} ROR_INTERSECT_INFO;
1352
Allocate a ROR_INTERSECT_INFO and initialize it to contain zero scans.
1355
ror_intersect_init()
1356
param Parameter from test_quick_select
1364
ROR_INTERSECT_INFO* ror_intersect_init(const optimizer::Parameter *param)
1366
ROR_INTERSECT_INFO *info;
1368
if (!(info= (ROR_INTERSECT_INFO*)param->mem_root->alloc_root(sizeof(ROR_INTERSECT_INFO))))
1371
if (!(buf= (my_bitmap_map*) param->mem_root->alloc_root(param->fields_bitmap_size)))
1373
if (info->covered_fields.init(buf, param->table->getShare()->sizeFields()))
1375
info->is_covering= false;
1376
info->index_scan_costs= 0.0;
1377
info->index_records= 0;
1378
info->out_rows= (double) param->table->cursor->stats.records;
1379
info->covered_fields.clearAll();
1383
1340
static void ror_intersect_cpy(ROR_INTERSECT_INFO *dst,
1384
1341
const ROR_INTERSECT_INFO *src)
1486
1443
static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info,
1487
const ROR_SCAN_INFO *scan)
1444
const optimizer::RorScanInfo *scan)
1489
1446
double selectivity_mult= 1.0;
1490
1447
KeyPartInfo *key_part= info->param->table->key_info[scan->keynr].key_part;
1507
1464
sel_arg= sel_arg->next_key_part)
1510
test(info->covered_fields.isBitSet(key_part[sel_arg->part].fieldnr-1));
1467
test(info->covered_fields.test(key_part[sel_arg->part].fieldnr-1));
1511
1468
if (cur_covered != prev_covered)
1513
1470
/* create (part1val, ..., part{n-1}val) tuple. */
1594
1551
static bool ror_intersect_add(ROR_INTERSECT_INFO *info,
1595
ROR_SCAN_INFO* ror_scan, bool is_cpk_scan)
1552
optimizer::RorScanInfo* ror_scan, bool is_cpk_scan)
1597
1554
double selectivity_mult= 1.0;
1620
1577
info->index_records += info->param->table->quick_rows[ror_scan->keynr];
1621
1578
info->index_scan_costs += ror_scan->index_read_cost;
1622
bitmap_union(&info->covered_fields, &ror_scan->covered_fields);
1623
if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields,
1624
&info->covered_fields))
1579
boost::dynamic_bitset<> tmp_bitset= ror_scan->bitsToBitset();
1580
info->covered_fields|= tmp_bitset;
1581
if (! info->is_covering && info->param->needed_fields.is_subset_of(info->covered_fields))
1626
1583
info->is_covering= true;
1630
1587
info->total_cost= info->index_scan_costs;
1631
if (!info->is_covering)
1588
if (! info->is_covering)
1633
1590
optimizer::CostVector sweep_cost;
1634
1591
Join *join= info->param->session->lex->select_lex.join;
1679
1636
optimizer::SEL_TREE *tree,
1680
1637
double read_time)
1682
ROR_SCAN_INFO **ror_scan_mark;
1683
ROR_SCAN_INFO **ror_scans_end= tree->ror_scans_end;
1639
optimizer::RorScanInfo **ror_scan_mark;
1640
optimizer::RorScanInfo **ror_scans_end= tree->ror_scans_end;
1685
for (ROR_SCAN_INFO **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1642
for (optimizer::RorScanInfo **scan= tree->ror_scans; scan != ror_scans_end; ++scan)
1686
1643
(*scan)->key_components=
1687
1644
param->table->key_info[(*scan)->keynr].key_parts;
1694
1651
/*I=set of all covering indexes */
1695
1652
ror_scan_mark= tree->ror_scans;
1697
MyBitmap *covered_fields= ¶m->tmp_covered_fields;
1698
if (! covered_fields->getBitmap())
1654
boost::dynamic_bitset<> *covered_fields= ¶m->tmp_covered_fields;
1655
if (covered_fields->empty())
1700
my_bitmap_map *tmp_bitmap= (my_bitmap_map*)param->mem_root->alloc_root(param->fields_bitmap_size);
1701
covered_fields->setBitmap(tmp_bitmap);
1657
covered_fields->resize(param->table->getShare()->sizeFields());
1703
if (! covered_fields->getBitmap() ||
1704
covered_fields->init(covered_fields->getBitmap(),
1705
param->table->getShare()->sizeFields()))
1707
covered_fields->clearAll();
1659
covered_fields->reset();
1709
1661
double total_cost= 0.0f;
1710
1662
ha_rows records=0;
1718
1670
number of first not covered component
1719
1671
Calculate and save these values for each of remaining scans.
1721
for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1673
for (optimizer::RorScanInfo **scan= ror_scan_mark; scan != ror_scans_end; ++scan)
1723
bitmap_subtract(&(*scan)->covered_fields, covered_fields);
1675
/* subtract one bitset from the other */
1676
(*scan)->subtractBitset(*covered_fields);
1724
1677
(*scan)->used_fields_covered=
1725
(*scan)->covered_fields.getBitsSet();
1726
(*scan)->first_uncovered_field=
1727
(*scan)->covered_fields.getFirst();
1678
(*scan)->getBitCount();
1679
(*scan)->first_uncovered_field= (*scan)->findFirstNotSet();
1730
1682
internal::my_qsort(ror_scan_mark, ror_scans_end-ror_scan_mark,
1731
sizeof(ROR_SCAN_INFO*),
1683
sizeof(optimizer::RorScanInfo*),
1732
1684
(qsort_cmp)cmp_ror_scan_info_covering);
1734
1686
/* I=I-first(I) */
1737
1689
if (total_cost > read_time)
1739
1691
/* F=F-covered by first(I) */
1740
bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields);
1741
all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields);
1742
} while ((++ror_scan_mark < ror_scans_end) && !all_covered);
1692
boost::dynamic_bitset<> tmp_bitset= (*ror_scan_mark)->bitsToBitset();
1693
*covered_fields|= tmp_bitset;
1694
all_covered= param->needed_fields.is_subset_of(*covered_fields);
1695
} while ((++ror_scan_mark < ror_scans_end) && ! all_covered);
1744
1697
if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1)
1765
1718
uint32_t best_num= (ror_scan_mark - tree->ror_scans);
1766
if (!(trp->first_scan= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* best_num)))
1719
if (!(trp->first_scan= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* best_num)))
1768
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(ROR_SCAN_INFO*));
1721
memcpy(trp->first_scan, tree->ror_scans, best_num*sizeof(optimizer::RorScanInfo*));
1769
1722
trp->last_scan= trp->first_scan + best_num;
1770
1723
trp->is_covering= true;
1771
1724
trp->read_cost= total_cost;
1857
Step1: Collect ROR-able SEL_ARGs and create ROR_SCAN_INFO for each of
1810
Step1: Collect ROR-able SEL_ARGs and create optimizer::RorScanInfo for each of
1858
1811
them. Also find and save clustered PK scan if there is one.
1860
ROR_SCAN_INFO **cur_ror_scan= NULL;
1861
ROR_SCAN_INFO *cpk_scan= NULL;
1813
optimizer::RorScanInfo **cur_ror_scan= NULL;
1814
optimizer::RorScanInfo *cpk_scan= NULL;
1862
1815
uint32_t cpk_no= 0;
1863
1816
bool cpk_scan_used= false;
1865
if (! (tree->ror_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)* param->keys)))
1818
if (! (tree->ror_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)* param->keys)))
1872
1825
for (idx= 0, cur_ror_scan= tree->ror_scans; idx < param->keys; idx++)
1874
ROR_SCAN_INFO *scan;
1827
optimizer::RorScanInfo *scan;
1875
1828
if (! tree->ror_scans_map.test(idx))
1877
if (!(scan= make_ror_scan(param, idx, tree->keys[idx])))
1830
if (! (scan= make_ror_scan(param, idx, tree->keys[idx])))
1879
1832
if (param->real_keynr[idx] == cpk_no)
1888
1841
tree->ror_scans_end= cur_ror_scan;
1890
1843
Ok, [ror_scans, ror_scans_end) is array of ptrs to initialized
1844
optimizer::RorScanInfo's.
1892
1845
Step 2: Get best ROR-intersection using an approximate algorithm.
1894
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(ROR_SCAN_INFO*),
1847
internal::my_qsort(tree->ror_scans, tree->n_ror_scans, sizeof(optimizer::RorScanInfo*),
1895
1848
(qsort_cmp)cmp_ror_scan_info);
1897
ROR_SCAN_INFO **intersect_scans= NULL; /* ROR scans used in index intersection */
1898
ROR_SCAN_INFO **intersect_scans_end= NULL;
1899
if (! (intersect_scans= (ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*) * tree->n_ror_scans)))
1850
optimizer::RorScanInfo **intersect_scans= NULL; /* ROR scans used in index intersection */
1851
optimizer::RorScanInfo **intersect_scans_end= NULL;
1852
if (! (intersect_scans= (optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*) * tree->n_ror_scans)))
1901
1854
intersect_scans_end= intersect_scans;
1903
1856
/* Create and incrementally update ROR intersection. */
1904
ROR_INTERSECT_INFO *intersect= NULL;
1905
ROR_INTERSECT_INFO *intersect_best= NULL;
1906
if (! (intersect= ror_intersect_init(param)) ||
1907
! (intersect_best= ror_intersect_init(param)))
1857
ROR_INTERSECT_INFO intersect(param);
1858
ROR_INTERSECT_INFO intersect_best(param);
1910
1860
/* [intersect_scans,intersect_scans_best) will hold the best intersection */
1911
ROR_SCAN_INFO **intersect_scans_best= NULL;
1861
optimizer::RorScanInfo **intersect_scans_best= NULL;
1912
1862
cur_ror_scan= tree->ror_scans;
1913
1863
intersect_scans_best= intersect_scans;
1914
while (cur_ror_scan != tree->ror_scans_end && !intersect->is_covering)
1864
while (cur_ror_scan != tree->ror_scans_end && ! intersect.is_covering)
1916
1866
/* S= S + first(R); R= R - first(R); */
1917
if (!ror_intersect_add(intersect, *cur_ror_scan, false))
1867
if (! ror_intersect_add(&intersect, *cur_ror_scan, false))
1919
1869
cur_ror_scan++;
1923
1873
*(intersect_scans_end++)= *(cur_ror_scan++);
1925
if (intersect->total_cost < min_cost)
1875
if (intersect.total_cost < min_cost)
1927
1877
/* Local minimum found, save it */
1928
ror_intersect_cpy(intersect_best, intersect);
1878
ror_intersect_cpy(&intersect_best, &intersect);
1929
1879
intersect_scans_best= intersect_scans_end;
1930
min_cost = intersect->total_cost;
1880
min_cost = intersect.total_cost;
1939
*are_all_covering= intersect->is_covering;
1889
*are_all_covering= intersect.is_covering;
1940
1890
uint32_t best_num= intersect_scans_best - intersect_scans;
1941
ror_intersect_cpy(intersect, intersect_best);
1891
ror_intersect_cpy(&intersect, &intersect_best);
1944
1894
Ok, found the best ROR-intersection of non-CPK key scans.
1945
1895
Check if we should add a CPK scan. If the obtained ROR-intersection is
1946
1896
covering, it doesn't make sense to add CPK scan.
1948
if (cpk_scan && !intersect->is_covering)
1898
if (cpk_scan && ! intersect.is_covering)
1950
if (ror_intersect_add(intersect, cpk_scan, true) &&
1951
(intersect->total_cost < min_cost))
1900
if (ror_intersect_add(&intersect, cpk_scan, true) &&
1901
(intersect.total_cost < min_cost))
1953
1903
cpk_scan_used= true;
1954
1904
intersect_best= intersect; //just set pointer here
1965
1915
if (! (trp->first_scan=
1966
(ROR_SCAN_INFO**)param->mem_root->alloc_root(sizeof(ROR_SCAN_INFO*)*best_num)))
1916
(optimizer::RorScanInfo**)param->mem_root->alloc_root(sizeof(optimizer::RorScanInfo*)*best_num)))
1968
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(ROR_SCAN_INFO*));
1918
memcpy(trp->first_scan, intersect_scans, best_num*sizeof(optimizer::RorScanInfo*));
1969
1919
trp->last_scan= trp->first_scan + best_num;
1970
trp->is_covering= intersect_best->is_covering;
1971
trp->read_cost= intersect_best->total_cost;
1920
trp->is_covering= intersect_best.is_covering;
1921
trp->read_cost= intersect_best.total_cost;
1972
1922
/* Prevent divisons by zero */
1973
ha_rows best_rows = double2rows(intersect_best->out_rows);
1923
ha_rows best_rows = double2rows(intersect_best.out_rows);
1974
1924
if (! best_rows)
1976
1926
set_if_smaller(param->table->quick_condition_rows, best_rows);
1977
1927
trp->records= best_rows;
1978
trp->index_scan_costs= intersect_best->index_scan_costs;
1928
trp->index_scan_costs= intersect_best.index_scan_costs;
1979
1929
trp->cpk_scan= cpk_scan_used? cpk_scan: NULL;
4028
3978
uint32_t mrr_buf_size,
4029
3979
memory::Root *parent_alloc)
4031
optimizer::QuickRangeSelect *quick= NULL;
4032
bool create_err= false;
4034
quick= new optimizer::QuickRangeSelect(param->session,
4036
param->real_keynr[idx],
3981
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(param->session,
3983
param->real_keynr[idx],
4044
get_quick_keys(param,
3989
if (get_quick_keys(param,
4046
3991
param->key[idx],
4292
4237
table_reference_st *ref,
4293
4238
ha_rows records)
4295
memory::Root *old_root, *alloc;
4296
optimizer::QuickRangeSelect *quick= NULL;
4240
memory::Root *old_root= NULL;
4241
memory::Root *alloc= NULL;
4297
4242
KeyInfo *key_info = &table->key_info[ref->key];
4298
4243
KEY_PART *key_part;
4299
4244
optimizer::QuickRange *range= NULL;
4301
bool create_err= false;
4302
4246
optimizer::CostVector cost;
4304
4248
old_root= session->mem_root;
4305
4249
/* The following call may change session->mem_root */
4306
quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0, &create_err);
4250
optimizer::QuickRangeSelect *quick= new optimizer::QuickRangeSelect(session, table, ref->key, 0, 0);
4307
4251
/* save mem_root set by QuickRangeSelect constructor */
4308
4252
alloc= session->mem_root;
5570
uint32_t optimizer::RorScanInfo::findFirstNotSet() const
5572
boost::dynamic_bitset<> map= bitsToBitset();
5573
for (boost::dynamic_bitset<>::size_type i= 0; i < map.size(); i++)
5584
size_t optimizer::RorScanInfo::getBitCount() const
5586
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5587
return tmp_bitset.count();
5591
void optimizer::RorScanInfo::subtractBitset(const boost::dynamic_bitset<>& in_bitset)
5593
boost::dynamic_bitset<> tmp_bitset= bitsToBitset();
5594
tmp_bitset-= in_bitset;
5595
covered_fields= tmp_bitset.to_ulong();
5599
boost::dynamic_bitset<> optimizer::RorScanInfo::bitsToBitset() const
5602
uint64_t conv= covered_fields;
5605
res.push_back((conv & 1) + '0');
5610
std::reverse(res.begin(), res.end());
5612
string final(covered_fields_size - res.length(), '0');
5614
return (boost::dynamic_bitset<>(final));
5626
5618
} /* namespace drizzled */