Indexes are used to find rows with specific column values
fast. Without an index, MySQL has to start with the first record
and then read through the whole table to find the relevant
rows. The larger the table, the more this costs. If the table has an index
for the columns in question, MySQL can quickly determine the position to
seek to in the middle of the data file without having to look at all the
data. If a table has 1,000 rows, this is at least 100 times faster than
reading sequentially. Note that if you need to access almost all 1,000
rows, it is faster to read sequentially, because that minimizes disk seeks.
Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and
FULLTEXT) are stored in B-trees. Exceptions are that indexes on
spatial column types use R-trees, and MEMORY (HEAP) tables
support hash indexes.
Strings are automatically prefix- and end-space compressed.
See Section 13.2.4, “CREATE INDEX Syntax”.
In general, indexes are used as described in the following discussion.
Characteristics specific to hash indexes (as used in MEMORY tables)
are described at the end of this section.
Indexes are used for these operations:
To quickly find the rows that match a WHERE clause.
To eliminate rows from consideration. If there is a choice between multiple
indexes, MySQL normally uses the index that finds the smallest number of
rows.
To retrieve rows from other tables when performing joins.
To find the MIN() or MAX() value for a specific indexed column
key_col. This is optimized by a preprocessor that checks whether you are
using WHERE on all key parts that occur beforekey_part_# = constant
key_col in the index. In this case, MySQL does a single key
lookup for each MIN() or MAX() expression and replace it
with a constant. If all expressions are replaced with constants, the
query returns at once. For example:
SELECT MIN(key_part2),MAX(key_part2)
FROMtbl_nameWHEREkey_part1=10;
To sort or group a table if the sorting or grouping is done on a leftmost
prefix of a usable key (for example, ORDER BY ). If all key parts are followed by key_part1, key_part2DESC, the key
is read in reverse order.
See Section 7.2.10, “How MySQL Optimizes ORDER BY”.
In some cases, a query can be optimized to retrieve values without
consulting the data rows. If a query uses only columns from a table that are
numeric and that form a leftmost prefix for some key, the selected values
may be retrieved from the index tree for greater speed:
SELECTkey_part3FROMtbl_nameWHEREkey_part1=1
Suppose that you issue the following SELECT statement:
mysql> SELECT * FROMtbl_nameWHERE col1=val1 AND col2=val2;
If a multiple-column index exists on col1 and col2, the
appropriate rows can be fetched directly. If separate single-column
indexes exist on col1 and col2, the optimizer tries to
find the most restrictive index by deciding which index finds fewer
rows and using that index to fetch the rows.
SELECT * FROMtbl_nameWHERE col1=val1;
SELECT * FROMtbl_nameWHERE col2=val2;
SELECT * FROMtbl_nameWHERE col2=val2 AND col3=val3;
SELECT * FROMtbl_nameWHEREkey_colLIKE 'Patrick%';
SELECT * FROMtbl_nameWHEREkey_colLIKE 'Pat%_ck%';
The following SELECT statements do not use indexes:
SELECT * FROMtbl_nameWHEREkey_colLIKE '%Patrick%';
SELECT * FROMtbl_nameWHEREkey_colLIKEother_col;
Searching using uses indexes if col_name IS NULLcol_name is indexed.
The following WHERE clauses use indexes:
... WHEREindex_part1=1 ANDindex_part2=2 ANDother_column=3
/*index= 1 ORindex= 2 */
... WHEREindex=1 OR A=10 ANDindex=2
/* optimized like "index_part1='hello'" */
... WHEREindex_part1='hello' ANDindex_part3=5
/* Can use index onindex1but not onindex2orindex3*/
... WHEREindex1=1 ANDindex2=2 ORindex1=3 ANDindex3=3;
These WHERE clauses do not use indexes:
/*index_part1is not used */
... WHEREindex_part2=1 ANDindex_part3=2
/* Index is not used in both AND parts */
... WHEREindex=1 OR A=10
/* No index spans all rows */
... WHEREindex_part1=1 ORindex_part2=10
Hash indexes have somewhat different characteristics than those just
discussed: