Bug #28554 Optimizer wrongly prefers index for (col = value) over (PK <= value)
| Submitted: | 21 May 2007 9:32 | Modified: | 22 May 2009 13:56 |
|---|---|---|---|
| Reporter: | Valeriy Kravchuk | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S3 (Non-critical) |
| Version: | 4.1.22, 5.0.42-BK | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | bfsm_2007_05_31, bfsm_2007_06_21, bfsm_2007_06_28 | ||
[21 May 2007 9:32]
Valeriy Kravchuk
[21 May 2007 9:35]
Valeriy Kravchuk
Dump of a table used for testing
Attachment: bug28554.sql.gz (application/gzip, text), 16.92 KiB.
[8 Aug 2007 0:10]
Sergey Petrunya
Investigation
-------------
With the query and the dataset provided by Valeriy I observe the following:
test_quick_select()
{
PRIMARY:
E(#rows)= 1496
cpu_cost= rows/TIME_FOR_COMPARE = 299.2
file->read_time() = 4.45
cost = 303.56
IDXA_status:
E(#rows)= 2075
cpu_cost= 415
get_index_only_read_time()=12.6
cost = 427.6
returned quick range select over PRIMARY key, cost=303.56
}
best_access_path()
{
consider doing 'ref' scan over IDXA_status, 1 keypart.
- reuse the range analyzer's estimate of 2075 rows.
- the cost is (using index tree only) 12.6 (like get_index_only_read_time
in test_quick_select)
consider using the quick selects. 303>59, so we decide using 'ref' access
}
This is how we end up choosing IDXA_status.
[8 Aug 2007 14:56]
Sergey Petrunya
Correction, this line: << consider using the quick selects. 303>59, so we decide using 'ref' access >> is incorrect, we do not compare 303 with 59.
[8 Aug 2007 16:16]
Sergey Petrunya
ref(IDXA_status) access cost:
best_time= (tmp=12.59) + (records=2075) /(TIME_FOR_COMPARE=5)= 427.59
best= 12.59
best_records=2075
range(PRIMARY) access cost:
tmp= record_count *
(s->quick->read_time +
(s->found_records - rnd_records)/(double) TIME_FOR_COMPARE
) =
= 1 * ( 303.56 + (1496 - 1496 * 0.75) / 5 ) =
= 1 * ( 303.56 + 74.75) = 378.36
comparison range vs. ref:
range:
tmp + rnd_records/5 = 378.36 + 224.4 = 602.76
(actually this is s->quick->read_time + s->found_records / TIME_FOR_COMPARE)
ref:
best + records/ 5 = 12.59 + 2075 / 5 = 12.59 + 415 = 427.59
That is, for the final comparisons we have those numbers:
cost(range(PRIMARY))=
(file->read_time(range) = 4.45) +
(#rows_in_range/TIME_FOR_COMPARE = 299.2) +
(#rows_in_range/TIME_FOR_COMPARE = 299.2) =
= 602.76
cost(ref(IDXA_status))=
(index_only_read_time(range) = 12.6) +
(#rows_in_range/TIME_FOR_COMPARE = 415) =
= 427.59
Here we see that we add the same value twice for the cost(range(PRIMARY)).
[10 Aug 2007 1:28]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/32343 ChangeSet@1.2562, 2007-08-10 05:27:32+04:00, sergefp@mysql.com +6 -0 BUG#28554: Optimizer wrongly prefers index for (key1=val1) over (PK<=val2) Make order in full/quick table scan calculation part of best_access_path(): - Do not have costs of condition evaluation added twice for quick select-based scans. - Do take join buffering into account for quick select scans - Correctly use the found_constraint heuristic. [this is a preliminary commit]
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.075 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.