You can provide hints to give the optimizer information about
how to choose indexes during query processing.
Section 13.2.7.1, “JOIN Syntax”, describes the general syntax for
specifying tables in a SELECT statement.
The syntax for an individual able, including that for index
hints, looks like this:
tbl_name[[AS]alias] [index_hint_list)]index_hint_list:index_hint[,index_hint] ...index_hint: USE {INDEX|KEY} [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list]) | IGNORE {INDEX|KEY} [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list) | FORCE {INDEX|KEY} [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)index_list:index_name[,index_name] ...
By specifying USE INDEX
(, you can
tell MySQL to use only one of the named indexes to find rows
in the table. The alternative syntax index_list)IGNORE INDEX
( can be used
to tell MySQL to not use some particular index or indexes.
These hints are useful if index_list)EXPLAIN shows
that MySQL is using the wrong index from the list of possible
indexes.
You can also use FORCE INDEX, which acts
like USE INDEX
( but with the
addition that a table scan is assumed to be
very expensive. In other words, a table
scan is used only if there is no way to use one of the given
indexes to find rows in the table.
index_list)
USE KEY, IGNORE KEY, and
FORCE KEY are synonyms for USE
INDEX, IGNORE INDEX, and
FORCE INDEX.
Each hint requires the names of indexes,
not the names of columns. The name of a PRIMARY
KEY is PRIMARY. To see the index
names for a table, use SHOW INDEX.
Prior to MySQL 5.1.17, USE INDEX,
IGNORE INDEX, and FORCE
INDEX affect only which indexes are used when MySQL
decides how to find rows in the table and how to process
joins. They do not affect whether an index is used when
resolving an ORDER BY or GROUP
BY clause.
Examples:
SELECT * FROM table1 USE INDEX (col1_index,col2_index) WHERE col1=1 AND col2=2 AND col3=3; SELECT * FROM table1 IGNORE INDEX (col3_index) WHERE col1=1 AND col2=2 AND col3=3;
As of MySQL 5.1.17, the syntax for index hints is extended in the following ways:
It is syntactically valid to specify an empty
index_list for USE
INDEX, which means “use no
indexes.” Specifying an empty
index_list for FORCE
INDEX or IGNORE INDEX is a
syntax error.
You can specify the scope of a index hint by adding a
FOR clause to the hint. This provides
more fine-grained control over the optimizer's selection
of an execution plan for various phases of query
processing. To affect only the indexes used when MySQL
decides how to find rows in the table and how to process
joins, use FOR JOIN. To influence index
usage for sorting or grouping rows, use FOR ORDER
BY or FOR GROUP BY. (However,
if there is a covering index for the table and it is used
to access the table, the optimizer will ignore
IGNORE INDEX FOR {ORDER BY|GROUP BY}
hints that disable that index.)
You can specify multiple index hints:
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;
It is not a error to name the same index in several hints (even within the same hint):
SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1,i1);
However, it is an error to mix USE
INDEX and FORCE INDEX for the
same table:
SELECT * FROM t1 USE INDEX FOR JOIN (i1) FORCE INDEX FOR JOIN (i2);
The default scope of index hints also is changed as of MySQL
5.1.17. Formerly, index hints applied only to how indexes are
used for retrieval of records and not during resolution of
ORDER BY or GROUP BY
clauses. As of 5.1.17, if you specify no
FOR clause for an index hint, the hint by
default applies to all parts of the statement. For example,
this hint:
IGNORE INDEX (i1)
is equivalent to this combination of hints:
IGNORE INDEX FOR JOIN (i1) IGNORE INDEX FOR ORDER BY (i1) IGNORE INDEX FOR GROUP BY (i1)
To cause the server to use the older behavior for hint scope
when no FOR clause is present (so that
hints apply only to row retrieval), enable the
old system variable at server startup. Take
care about enabling this variable in a replication setup. With
statement-based binary logging, having different modes for the
master and slaves might lead to replication errors.
When index hints are processed, they are are collected in a
single list by type (USE,
FORCE, IGNORE) and by
scope (FOR JOIN, FOR ORDER
BY, FOR GROUP BY). For example:
SELECT * FROM t1 USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2);
is equivalent to:
SELECT * FROM t1 USE INDEX (i1,i2) IGNORE INDEX (i2);
The index hints then are applied for each scope in the following order:
{USE|FORCE} INDEX is applied if
present. (If not, the optimizer-determined set of indexes
is used.)
IGNORE INDEX is applied over the result
of the previous step. For example:
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX (i2) USE INDEX (i2)
is equivalent to:
SELECT * FROM t1 USE INDEX (i1).

User Comments
Add your own comment.