CREATE [ONLINE|OFFLINE] [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name[index_type] ONtbl_name(index_col_name,...) [index_option] ...index_col_name:col_name[(length)] [ASC | DESC]index_type: USING {BTREE | HASH}index_option: KEY_BLOCK_SIZE [=]value|index_type| WITH PARSERparser_name| COMMENT 'string'
CREATE INDEX is mapped to an
ALTER TABLE statement to create
indexes. See Section 13.1.7, “ALTER TABLE Syntax”.
CREATE INDEX cannot be used to
create a PRIMARY KEY; use
ALTER TABLE instead. For more
information about indexes, see Section 8.3.1, “How MySQL Uses Indexes”.
Normally, you create all indexes on a table at the time the table
itself is created with CREATE
TABLE. See Section 13.1.17, “CREATE TABLE Syntax”. This
guideline is especially important for
InnoDB tables, where the primary key
determines the physical layout of rows in the data file.
CREATE INDEX enables you to add
indexes to existing tables.
A column list of the form (col1,col2,...)
creates a multiple-column index. Index key values are formed by
concatenating the values of the given columns.
For string columns, indexes can be created that use only the
leading part of column values, using
syntax to specify an index prefix length:
col_name(length)
Prefixes can be specified for
CHAR,
VARCHAR,
BINARY, and
VARBINARY column indexes.
Prefixes must be specified for
BLOB and
TEXT column indexes.
Prefix limits are measured in bytes, whereas the prefix length
in CREATE TABLE,
ALTER TABLE, and
CREATE INDEX statements is
interpreted as number of characters for nonbinary string types
(CHAR,
VARCHAR,
TEXT) and number of bytes for
binary string types (BINARY,
VARBINARY,
BLOB). Take this into account
when specifying a prefix length for a nonbinary string column
that uses a multibyte character set.
For spatial columns, prefix values cannot be given, as described later in this section.
The statement shown here creates an index using the first 10
characters of the name column (assuming that
name has a nonbinary string type):
CREATE INDEX part_of_name ON customer (name(10));
If names in the column usually differ in the first 10 characters,
this index should not be much slower than an index created from
the entire name column. Also, using column
prefixes for indexes can make the index file much smaller, which
could save a lot of disk space and might also speed up
INSERT operations.
Prefix support and lengths of prefixes (where supported) are
storage engine dependent. For example, a prefix can be up to 767
bytes long for InnoDB tables or 3072
bytes if the innodb_large_prefix
option is enabled. For MyISAM tables,
the prefix limit is 1000 bytes. The
NDB storage engine does not support
prefixes (see
Section 18.1.6.6, “Unsupported or Missing Features in NDB Cluster”).
Indexes on variable-width columns of
NDBCLUSTER tables are created online;
that is, without any table copying. The table is not locked
against access from other MySQL Cluster API nodes, although it is
locked against other operations on the same
API node for the duration of the operation. This is done
automatically by the server whenever it determines that it is
possible to do so; you do not have to use any special SQL syntax
or server options to cause it to happen.
In standard MySQL 5.5 releases, it is not possible to
override the server when it determines that an index is to be
created without table copying. In MySQL Cluster, you can create
indexes offline (which causes the table to be locked to all API
nodes in the cluster) using the OFFLINE
keyword. The rules and limitations governing CREATE
OFFLINE INDEX and CREATE ONLINE INDEX
are the same as for ALTER OFFLINE TABLE ... ADD
INDEX and ALTER ONLINE TABLE ... ADD
INDEX. You cannot cause the noncopying creation of an
index that would normally be created offline by using the
ONLINE keyword: If it is not possible to
perform the CREATE INDEX operation
without table copying, the server ignores the
ONLINE keyword. For more information, see
Section 13.1.7.2, “ALTER TABLE Online Operations in MySQL Cluster”.
The ONLINE and OFFLINE
keywords are available only in MySQL Cluster; attempting to use
these keywords in standard MySQL Server 5.5 releases
results in a syntax error.
A UNIQUE index creates a constraint such that
all values in the index must be distinct. An error occurs if you
try to add a new row with a key value that matches an existing
row. For all engines, a UNIQUE index permits
multiple NULL values for columns that can
contain NULL. If you specify a prefix value for
a column in a UNIQUE index, the column values
must be unique within the prefix.
FULLTEXT indexes are supported only for
MyISAM tables and can include only
CHAR,
VARCHAR, and
TEXT columns. Indexing always
happens over the entire column; column prefix indexing is not
supported and any prefix length is ignored if specified. See
Section 12.9, “Full-Text Search Functions”, for details of operation.
The MyISAM,
InnoDB,
NDB, and
ARCHIVE storage engines support
spatial columns such as (POINT and
GEOMETRY.
(Section 11.5, “Extensions for Spatial Data”, describes the spatial data
types.) However, support for spatial column indexing varies among
engines. Spatial and nonspatial indexes are available according to
the following rules.
Spatial indexes (created using SPATIAL INDEX)
have these characteristics:
Available only for MyISAM tables.
Specifying SPATIAL INDEX for other storage
engines results in an error.
Indexed columns must be NOT NULL.
Column prefix lengths are prohibited. The full width of each column is indexed.
Characteristics of nonspatial indexes (created with
INDEX, UNIQUE, or
PRIMARY KEY):
Permitted for any storage engine that supports spatial columns
except ARCHIVE.
Columns can be NULL unless the index is a
primary key.
For each spatial column in a non-SPATIAL
index except POINT columns, a
column prefix length must be specified. (This is the same
requirement as for indexed BLOB
columns.) The prefix length is given in bytes.
The index type for a non-SPATIAL index
depends on the storage engine. Currently, B-tree is used.
You can add an index on a column that can have
NULL values only for
MyISAM,
InnoDB, and
MEMORY tables
You can add an index on a BLOB
or TEXT column only for
MyISAM and
InnoDB tables
An index_col_name specification can end
with ASC or DESC. These
keywords are permitted for future extensions for specifying
ascending or descending index value storage. Currently, they are
parsed but ignored; index values are always stored in ascending
order.
Following the index column list, index options can be given. An
index_option value can be any of the
following:
KEY_BLOCK_SIZE [=]
value
For MyISAM tables,
KEY_BLOCK_SIZE optionally specifies the
size in bytes to use for index key blocks. The value is
treated as a hint; a different size could be used if
necessary. A KEY_BLOCK_SIZE value specified
for an individual index definition overrides a table-level
KEY_BLOCK_SIZE value.
KEY_BLOCK_SIZE is not supported at the
index level for InnoDB tables.
See Section 13.1.17, “CREATE TABLE Syntax”.
index_type
Some storage engines permit you to specify an index type when
creating an index.
Table 13.1, “Index Types Per Storage Engine”
shows the permissible index type values supported by different
storage engines. Where multiple index types are listed, the
first one is the default when no index type specifier is
given. Storage engines not listed in the table do not support
an index_type clause in index
definitions.
Example:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index ON lookup (id) USING BTREE;
The index_type clause cannot be
used for FULLTEXT INDEX or SPATIAL
INDEX specifications. Full-text index implementation
is storage engine dependent. Spatial indexes are implemented
as R-tree indexes.
BTREE indexes are implemented by the
NDB storage engine as T-tree
indexes.
For indexes on NDB table
columns, the USING option can be
specified only for a unique index or primary key.
USING HASH prevents the creation of an
ordered index; otherwise, creating a unique index or primary
key on an NDB table
automatically results in the creation of both an ordered
index and a hash index, each of which indexes the same set
of columns.
For unique indexes that include one or more
NULL columns of an
NDB table, the hash index can
be used only to look up literal values, which means that
IS [NOT] NULL conditions require a full
scan of the table. One workaround is to make sure that a
unique index using one or more NULL
columns on such a table is always created in such a way that
it includes the ordered index; that is, avoid employing
USING HASH when creating the index.
If you specify an index type that is not valid for a given
storage engine, but another index type is available that the
engine can use without affecting query results, the engine
uses the available type. The parser recognizes
RTREE as a type name, but currently this
cannot be specified for any storage engine.
Use of the index_type option
before the ON
clause is
deprecated; support for use of the option in this position
will be removed in a future MySQL release. If an
tbl_nameindex_type option is given in
both the earlier and later positions, the final option
applies.
TYPE
is recognized as a synonym for type_nameUSING
. However,
type_nameUSING is the preferred form.
For the storage engines that support an
index_type option,
Table 13.2, “Storage Engine Index Characteristics”
shows some characteristics of index use.
Table 13.2 Storage Engine Index Characteristics
| Storage Engine | Index Type | Index Class | Stores NULL Values | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
|---|---|---|---|---|---|---|
InnoDB | BTREE | Primary key | No | No | N/A | N/A |
| Unique | Yes | Yes | Index | Index | ||
| Key | Yes | Yes | Index | Index | ||
MyISAM | BTREE | Primary key | No | No | N/A | N/A |
| Unique | Yes | Yes | Index | Index | ||
| Key | Yes | Yes | Index | Index | ||
| Inapplicable | FULLTEXT | Yes | Yes | Table | Table | |
| Inapplicable | SPATIAL | No | No | N/A | N/A | |
MEMORY | HASH | Primary key | No | No | N/A | N/A |
| Unique | Yes | Yes | Index | Index | ||
| Key | Yes | Yes | Index | Index | ||
BTREE | Primary | No | No | N/A | N/A | |
| Unique | Yes | Yes | Index | Index | ||
| Key | Yes | Yes | Index | Index | ||
NDB | BTREE | Primary key | No | No | Index | Index |
| Unique | Yes | Yes | Index | Index | ||
| Key | Yes | Yes | Index | Index | ||
HASH | Primary | No | No | Table (see note 1) | Table (see note 1) | |
| Unique | Yes | Yes | Table (see note 1) | Table (see note 1) | ||
| Key | Yes | Yes | Table (see note 1) | Table (see note 1) |
Table note:
1. If USING HASH is specified that prevents
creation of an implicit ordered index.
WITH PARSER
parser_name
This option can be used only with FULLTEXT
indexes. It associates a parser plugin with the index if
full-text indexing and searching operations need special
handling. See Section 24.2, “The MySQL Plugin API”, for details on
creating plugins.
COMMENT '
string'
As of MySQL 5.5.3, index definitions can include an optional comment of up to 1024 characters.