Bug #16166 cannot force index merge
| Submitted: | 3 Jan 2006 22:12 | Modified: | 13 Jan 2006 0:17 |
|---|---|---|---|
| Reporter: | Kolbe Kegel | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
| Version: | 5.0.17 | OS: | Linux (Linux) |
| Assigned to: | Sergey Petrunya | CPU Architecture: | Any |
[4 Jan 2006 6:57]
Igor Babaev
FORCE INDEX(idx1, idx2) tells the server that using table scan is much more expensive than using index idx1 OR idx2 OR both of them.
[4 Jan 2006 7:19]
Kolbe Kegel
The problem is that FORCE INDEX *prevents* index merge from happening in a situation where index merge is normally selected by the optimizer.
The first two explains of the original example give the following output:
mysql 5.0.17-max (root) "test"> explain select * from t1 WHERE cola = 'foo' AND colb = 'bar' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ref
possible_keys: cola,colb
key: cola
key_len: 3
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
mysql 5.0.17-max (root) "test"> explain select * from t1 force index (cola, colb) WHERE cola = 'foo' AND colb = 'bar' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ref
possible_keys: cola,colb
key: cola
key_len: 3
ref: const
rows: 1
Extra: Using where
1 row in set (0.00 sec)
The last two explains of the original example give the following output:
mysql 5.0.17-max (root) "test"> explain select * from t1 WHERE cola = 'foo' AND colb = 'bar' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: index_merge
possible_keys: cola,colb
key: cola,colb
key_len: 3,3
ref: NULL
rows: 14
Extra: Using intersect(cola,colb); Using where; Using index
1 row in set (0.00 sec)
mysql 5.0.17-max (root) "test"> explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ref
possible_keys: cola,colb
key: cola
key_len: 3
ref: const
rows: 555
Extra: Using where
1 row in set (0.00 sec)
[11 Jan 2006 12:58]
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/910
[12 Jan 2006 7:46]
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/946
[12 Jan 2006 10:12]
Sergey Petrunya
The fix has been pushed into 5.0.19 tree.
Note for the changelog:
For query that used Index Merge intersection algorithm for indexes idx1... idxN , adding "FORCE INDEX (idx1,...,idxN) caused the Index Merge intersection not to be used anymore ("ref" on one of idx{i} was used instead).
[13 Jan 2006 0:17]
Mike Hillyer
Added to 5.0.19 changelog:
<listitem>
<para>
The <literal>FORCE INDEX</literal> keyword in a query would
prevent an index merge from being used where an index merge
would normally be chosen by the optimizer. (Bug #16166)
</para>
</listitem>
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.056 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.
Description: It is sometimes not possible to force index merge. This limitation can make it impossible to use index merge in queries with a range scan (per documentat, FORCE INDEX is required in some situations where a range scan occurs). How to repeat: DROP TABLE IF EXISTS t1; CREATE TABLE t1 (cola char(3) not null, colb char(3) not null, key (cola), key (colb)); INSERT INTO t1 VALUES ('foo','bar'),('fuz','baz'); explain select * from t1 WHERE cola = 'foo' AND colb = 'bar'; explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar'; -- we need to have to have a few thousand more rows for index merge to work... INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola = 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; OPTIMIZE TABLE t1; explain select * from t1 WHERE cola = 'foo' AND colb = 'bar'; explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar'; -- Apparently there is a certain threshhold before index merge is used.... this should be documented somewhere if this does not already exist INSERT INTO t1 SELECT * from t1 WHERE cola <> 'foo'; OPTIMIZE TABLE t1; explain select * from t1 WHERE cola = 'foo' AND colb = 'bar'; explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar'; Suggested fix: Using FORCE INDEX should always cause the optimizer to do an index merge if the index merge is logically possible.