CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEXindex_name
[index_type
] ONtbl_name
(key_part
,...) [index_option
] [algorithm_option
|lock_option
] ...key_part
: {col_name
[(length
)] | (expr
)} [ASC | DESC]index_option
: { KEY_BLOCK_SIZE [=]value
|index_type
| WITH PARSERparser_name
| COMMENT 'string
' | {VISIBLE | INVISIBLE} | ENGINE_ATTRIBUTE [=] 'string
' | SECONDARY_ENGINE_ATTRIBUTE [=] 'string
' }index_type
: USING {BTREE | HASH}algorithm_option
: ALGORITHM [=] {DEFAULT | INPLACE | COPY}lock_option
: LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
Normally, you create all indexes on a table at the time the table itself is created with 通常,在使用CREATE TABLE
. CREATE TABLE
创建表本身时,您会在表上创建所有索引。See Section 13.1.20, “CREATE TABLE Statement”. 请参阅第13.1.20节,“CREATE TABLE语句”。This guideline is especially important for 该指南对于InnoDB
tables, where the primary key determines the physical layout of rows in the data file. InnoDB
表尤其重要,其中主键决定数据文件中行的物理布局。CREATE INDEX
enables you to add indexes to existing tables.CREATE INDEX
使您能够向现有表添加索引。
CREATE INDEX
is mapped to an ALTER TABLE
statement to create indexes. CREATE INDEX
映射到ALTER TABLE
语句以创建索引。See Section 13.1.9, “ALTER TABLE Statement”. 请参阅第13.1.9节,“ALTER TABLE语句”。CREATE INDEX
cannot be used to create a PRIMARY KEY
; use ALTER TABLE
instead. CREATE INDEX
不能用于创建PRIMARY KEY
;要创建PRIMARY KEY
请改用ALTER TABLE
。For more information about indexes, see Section 8.3.1, “How MySQL Uses Indexes”.有关索引的更多信息,请参阅第8.3.1节,“MySQL如何使用索引”。
InnoDB
supports secondary indexes on virtual columns. InnoDB
支持虚拟列上的辅助索引。For more information, see Section 13.1.20.9, “Secondary Indexes and Generated Columns”.有关更多信息,请参阅第13.1.20.9节,“二级索引和生成列”。
When the 启用innodb_stats_persistent
setting is enabled, run the ANALYZE TABLE
statement for an InnoDB
table after creating an index on that table.innodb_stats_persistent
设置后,在对InnoDB
表创建索引后,为该表运行ANALYZE TABLE
语句。
Beginning with MySQL 8.0.17, the 从MySQL 8.0.17开始,密钥部分规范的expr
for a key_part
specification can take the form (CAST
to create a multi-valued index on a json_expression
AS type
ARRAY)JSON
column. expr
可以采用以下形式(CAST
以在JSON列上创建多值索引。json_expression
AS type
ARRAY)See Multi-Valued Indexes.请参阅多值索引。
An index specification of the form (
creates an index with multiple key parts. key_part1
, key_part2
, ...)(
形式的索引规范创建了一个包含多个键部分的索引。key_part1
, key_part2
, ...)Index key values are formed by concatenating the values of the given key parts. 索引键值是通过连接给定键部分的值形成的。For example 例如,(col1, col2, col3)
specifies a multiple-column index with index keys consisting of values from col1
, col2
, and col3
.(col1, col2, col3)
指定一个多列索引,索引键由col1
、col2
和col3
中的值组成。
A key_part
specification can end with ASC
or DESC
to specify whether index values are stored in ascending or descending order. key_part
规范可以以ASC
或DESC
结尾,以指定索引值是按升序还是降序存储。The default is ascending if no order specifier is given. 如果未指定顺序说明符,则默认值为升序。ASC
and DESC
are not permitted for HASH
indexes. HASH
索引不允许使用ASC
和DESC
。多值索引也不支持ASC
and DESC
are also not supported for multi-valued indexes. ASC
和DESC
。As of MySQL 8.0.12, 从MySQL 8.0.12开始,ASC
and DESC
are not permitted for SPATIAL
indexes.SPATIAL
索引不允许使用ASC
和DESC
。
The following sections describe different aspects of the 以下各节介绍CREATE INDEX
statement:CREATE INDEX
语句的不同方面:
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
)
语法指定索引前缀长度:col_name
(length
)
Prefixes can be specified for 可以为CHAR
, VARCHAR
, BINARY
, and VARBINARY
key parts.CHAR
、VARCHAR
、BINARY
和VARBINARY
键部分指定前缀。
Prefixes must be specified for 必须为BLOB
and TEXT
key parts. BLOB
和TEXT
键部分指定前缀。Additionally, 此外,BLOB
and TEXT
columns can be indexed only for InnoDB
, MyISAM
, and BLACKHOLE
tables.BLOB
和TEXT
列只能为InnoDB
、MyISAM
和BLACKHOLE
表编制索引。
Prefix limits are measured in bytes. 前缀限制以字节为单位。However, prefix lengths for index specifications in 但是,CREATE TABLE
, ALTER TABLE
, and CREATE INDEX
statements are interpreted as number of characters for nonbinary string types (CHAR
, VARCHAR
, TEXT
) and number of bytes for binary string types (BINARY
, VARBINARY
, BLOB
). CREATE TABLE
、ALTER TABLE
和CREATE INDEX
语句中索引规范的前缀长度被解释为非二进制字符串类型(CHAR
、VARCHAR
、TEXT
)的字符数和二进制字符串类型(BINARY
、VARBINARY
、BLOB斑点)的字节数。Take this into account when specifying a prefix length for a nonbinary string column that uses a multibyte character set.为使用多字节字符集的非二进制字符串列指定前缀长度时,请考虑这一点。
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 that use the REDUNDANT
or COMPACT
row format. REDUNDANT
(冗余)或COMPACT
(紧凑)行格式的InnoDB
表,前缀的长度可以高达767字节。The prefix length limit is 3072 bytes for 对于使用InnoDB
tables that use the DYNAMIC
or COMPRESSED
row format. DYNAMIC
(动态)或COMPRESSED
(压缩)行格式的InnoDB
表,前缀长度限制为3072字节。For 对于MyISAM
tables, the prefix length limit is 1000 bytes. MyISAM
表,前缀长度限制为1000字节。The NDB
storage engine does not support prefixes (see Section 23.1.7.6, “Unsupported or Missing Features in NDB Cluster”).NDB
存储引擎不支持前缀(请参阅第23.1.7.6节,“NDB群集中不支持或缺少的功能”)。
If a specified index prefix exceeds the maximum column data type size, 如果指定的索引前缀超过最大列数据类型大小,则CREATE INDEX
handles the index as follows:CREATE INDEX
将按如下方式处理索引:
For a nonunique index, either an error occurs (if strict SQL mode is enabled), or the index length is reduced to lie within the maximum column data type size and a warning is produced (if strict SQL mode is not enabled).对于非唯一索引,要么发生错误(如果启用了严格SQL模式),要么索引长度减小到最大列数据类型大小范围内,并生成警告(如果未启用严格SQL模式)。
For a unique index, an error occurs regardless of SQL mode because reducing the index length might enable insertion of nonunique entries that do not meet the specified uniqueness requirement.对于唯一索引,无论SQL模式如何,都会发生错误,因为减少索引长度可能会导致插入不符合指定唯一性要求的非唯一项。
The statement shown here creates an index using the first 10 characters of the 此处显示的语句使用name
column (assuming that name
has a nonbinary string type):name
列的前10个字符创建索引(假设name
具有非二进制字符串类型):
CREATE INDEX part_of_name ON customer (name(10));
If names in the column usually differ in the first 10 characters, lookups performed using this index should not be much slower than using an index created from the entire 如果列中的名称在前10个字符中通常不同,则使用此索引执行的查找不应比使用从整个name
column. name
列创建的索引慢多少。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.INSERT
操作。
A “normal” index indexes column values or prefixes of column values. “普通”索引索引列值或列值的前缀。For example, in the following table, the index entry for a given 例如,在下表中,给定t1
row includes the full col1
value and a prefix of the col2
value consisting of its first 10 characters:t1
行的索引项包括完整的col1
值和col2
值的前缀,col2
值由其前10个字符组成:
CREATE TABLE t1 ( col1 VARCHAR(10), col2 VARCHAR(20), INDEX (col1, col2(10)) );
MySQL 8.0.13 and higher supports functional key parts that index expression values rather than column or column prefix values. MySQL 8.0.13及更高版本支持索引表达式值而不是列或列前缀值的功能关键部分。Use of functional key parts enables indexing of values not stored directly in the table. 使用功能键部件可以对表中未直接存储的值进行索引。Examples:示例:
CREATE TABLE t1 (col1 INT, col2 INT, INDEX func_index ((ABS(col1)))); CREATE INDEX idx1 ON t1 ((col1 + col2)); CREATE INDEX idx2 ON t1 ((col1 + col2), (col1 - col2), col1); ALTER TABLE t1 ADD INDEX ((col1 * 40) DESC);
An index with multiple key parts can mix nonfunctional and functional key parts.包含多个关键部分的索引可以混合非功能性和功能性关键部分。
功能键部分支持ASC
and DESC
are supported for functional key parts.ASC
和DESC
。
Functional key parts must adhere to the following rules. 功能关键部件必须遵守以下规则。An error occurs if a key part definition contains disallowed constructs.如果关键零件定义包含不允许的构件,则会发生错误。
In index definitions, enclose expressions within parentheses to distinguish them from columns or column prefixes. 在索引定义中,将表达式括在括号内,以区别于列或列前缀。For example, this is permitted; the expressions are enclosed within parentheses:例如,这是允许的;表达式用括号括起来:
INDEX ((col1 + col2), (col3 - col4))
This produces an error; the expressions are not enclosed within parentheses:这会产生错误;表达式不包含在括号内:
INDEX (col1 + col2, col3 - col4)
A functional key part cannot consist solely of a column name. 功能键部分不能仅由列名组成。For example, this is not permitted:例如,这是不允许的:
INDEX ((col1), (col2))
Instead, write the key parts as nonfunctional key parts, without parentheses:相反,将关键部分写为非功能关键部分,不带括号:
INDEX (col1, col2)
A functional key part expression cannot refer to column prefixes. 功能键部分表达式不能引用列前缀。For a workaround, see the discussion of 有关变通解决方法,请参阅本节后面对SUBSTRING()
and CAST()
later in this section.SUBSTRING()
和CAST()
的讨论。
Functional key parts are not permitted in foreign key specifications.外键规范中不允许使用功能键部件。
For 对于CREATE TABLE ... LIKE
, the destination table preserves functional key parts from the original table.CREATE TABLE ... LIKE
,目标表保留原始表中的功能键部分。
Functional indexes are implemented as hidden virtual generated columns, which has these implications:函数索引实现为隐藏的虚拟生成列,这具有以下含义:
Each functional key part counts against the limit on total number of table columns; see Section 8.4.7, “Limits on Table Column Count and Row Size”.每个功能关键部分都会根据表列总数的限制进行计数;请参阅第8.4.7节,“表列计数和行大小限制”。
Functional key parts inherit all restrictions that apply to generated columns. 功能键部件继承应用于生成列的所有限制。Examples:示例:
Only functions permitted for generated columns are permitted for functional key parts.只有生成列允许的功能才允许用于功能关键部件。
Subqueries, parameters, variables, stored functions, and loadable functions are not permitted.不允许使用子查询、参数、变量、存储函数和可加载函数。
For more information about applicable restrictions, see Section 13.1.20.8, “CREATE TABLE and Generated Columns”, and Section 13.1.9.2, “ALTER TABLE and Generated Columns”.有关适用限制的更多信息,请参阅第13.1.20.8节,“创建表和生成列”和第13.1.9.2节,“更改表和生成列”。
The virtual generated column itself requires no storage. 虚拟生成的列本身不需要存储。The index itself takes up storage space as any other index.索引本身与任何其他索引一样占用存储空间。
包含功能关键部分的索引支持UNIQUE
is supported for indexes that include functional key parts. UNIQUE
。However, primary keys cannot include functional key parts. 但是,主键不能包括功能键部件。A primary key requires the generated column to be stored, but functional key parts are implemented as virtual generated columns, not stored generated columns.主键要求存储生成的列,但功能键部分实现为虚拟生成列,而不是存储生成列。
SPATIAL
and FULLTEXT
indexes cannot have functional key parts.SPATIAL
(空间)索引和FULLTEXT
(全文)索引不能包含功能键部分。
If a table contains no primary key, 如果表不包含主键,InnoDB
automatically promotes the first UNIQUE NOT NULL
index to the primary key. InnoDB
会自动将第一个唯一的非空索引提升到主键。This is not supported for 对于具有功能键部分的UNIQUE NOT NULL
indexes that have functional key parts.UNIQUE NOT NULL
索引,这是不受支持的。
Nonfunctional indexes raise a warning if there are duplicate indexes. 如果存在重复索引,则非功能索引将发出警告。Indexes that contain functional key parts do not have this feature.包含功能键部分的索引没有此功能。
To remove a column that is referenced by a functional key part, the index must be removed first. Otherwise, an error occurs.要删除功能键部件引用的列,必须先删除索引。否则,将发生错误。
Although nonfunctional key parts support a prefix length specification, this is not possible for functional key parts. 尽管非功能性关键部件支持前缀长度规范,但功能性关键部件不支持前缀长度规范。The solution is to use 解决方案是使用SUBSTRING()
(or CAST()
, as described later in this section). SUBSTRING()
(或CAST()
,如本节后面所述)。For a functional key part containing the 对于包含要在查询中使用的SUBSTRING()
function to be used in a query, the WHERE
clause must contain SUBSTRING()
with the same arguments. SUBSTRING()
函数的函数键部分,WHERE
子句必须包含具有相同参数的SUBSTRING()
。In the following example, only the second 在以下示例中,只有第二个SELECT
is able to use the index because that is the only query in which the arguments to SUBSTRING()
match the index specification:SELECT
可以使用索引,因为这是SUBSTRING()
的参数与索引规范匹配的唯一查询:
CREATE TABLE tbl ( col1 LONGTEXT, INDEX idx1 ((SUBSTRING(col1, 1, 10))) ); SELECT * FROM tbl WHERE SUBSTRING(col1, 1, 9) = '123456789'; SELECT * FROM tbl WHERE SUBSTRING(col1, 1, 10) = '1234567890';
Functional key parts enable indexing of values that cannot be indexed otherwise, such as 功能键部件支持对无法以其他方式索引的值(如JSON
values. JSON
值)进行索引。However, this must be done correctly to achieve the desired effect. 但是,必须正确地执行此操作才能达到预期效果。For example, this syntax does not work:例如,此语法不起作用:
CREATE TABLE employees ( data JSON, INDEX ((data->>'$.name')) );
The syntax fails because:语法失败,因为:
The ->>
operator translates into JSON_UNQUOTE(JSON_EXTRACT(...))
.->>
运算符翻译为JSON_UNQUOTE(JSON_EXTRACT(...))
。
JSON_UNQUOTE()
returns a value with a data type of LONGTEXT
, and the hidden generated column thus is assigned the same data type.JSON_UNQUOTE()
返回一个数据类型为LONGTEXT
的值,因此生成的隐藏列被指定为相同的数据类型。
MySQL cannot index MySQL无法索引键部分没有前缀长度的LONGTEXT
columns specified without a prefix length on the key part, and prefix lengths are not permitted in functional key parts.LONGTEXT
列,并且功能键部分中不允许前缀长度。
To index the 要为JSON
column, you could try using the CAST()
function as follows:JSON
列编制索引,可以尝试使用CAST()
函数,如下所示:
CREATE TABLE employees ( data JSON, INDEX ((CAST(data->>'$.name' AS CHAR(30)))) );
The hidden generated column is assigned the 生成的隐藏列被分配了VARCHAR(30)
data type, which can be indexed. But this approach produces a new issue when trying to use the index:VARCHAR(30)
数据类型,该数据类型可以被索引。但这种方法在尝试使用索引时产生了一个新问题:
CAST()
returns a string with the collation utf8mb4_0900_ai_ci
(the server default collation).CAST()
返回具有排序规则utf8mb4_0900_ai_ci
(服务器默认排序规则)的字符串。
JSON_UNQUOTE()
returns a string with the collation utf8mb4_bin
(hard coded).JSON_UNQUOTE()
返回排序规则为utf8mb4_bin
(硬编码)的字符串。
As a result, there is a collation mismatch between the indexed expression in the preceding table definition and the 因此,前面表定义中的索引表达式与以下查询中的WHERE
clause expression in the following query:WHERE
子句表达式之间存在排序规则不匹配:
SELECT * FROM employees WHERE data->>'$.name' = 'James';
The index is not used because the expressions in the query and the index differ. 由于查询和索引中的表达式不同,因此未使用索引。To support this kind of scenario for functional key parts, the optimizer automatically strips 为了支持函数键部件的这种情况,优化器在查找要使用的索引时自动剥离CAST()
when looking for an index to use, but only if the collation of the indexed expression matches that of the query expression. CAST()
,但前提是索引表达式的排序规则与查询表达式的排序规则匹配。For an index with a functional key part to be used, either of the following two solutions work (although they differ somewhat in effect):对于要使用功能键部分的索引,以下两种解决方案中的任何一种都有效(尽管它们在效果上有所不同):
Solution 1. Assign the indexed expression the same collation as 解决方案1.为索引表达式指定与JSON_UNQUOTE()
:JSON_UNQUOTE()
相同的排序规则:
CREATE TABLE employees ( data JSON, INDEX idx ((CAST(data->>"$.name" AS CHAR(30)) COLLATE utf8mb4_bin)) ); INSERT INTO employees VALUES ('{ "name": "james", "salary": 9000 }'), ('{ "name": "James", "salary": 10000 }'), ('{ "name": "Mary", "salary": 12000 }'), ('{ "name": "Peter", "salary": 8000 }'); SELECT * FROM employees WHERE data->>'$.name' = 'James';
The ->>
operator is the same as JSON_UNQUOTE(JSON_EXTRACT(...))
, and JSON_UNQUOTE()
returns a string with collation utf8mb4_bin
. ->>
运算符与JSON_UNQUOTE(JSON_EXTRACT(...))
相同,JSON_UNQUOTE()
返回排序规则为utf8mb4_bin
的字符串。The comparison is thus case-sensitive, and only one row matches:因此,比较区分大小写,只有一行匹配:
+------------------------------------+ | data | +------------------------------------+ | {"name": "James", "salary": 10000} | +------------------------------------+
Solution 2. Specify the full expression in the query:解决方案2.在查询中指定完整表达式:
CREATE TABLE employees ( data JSON, INDEX idx ((CAST(data->>"$.name" AS CHAR(30)))) ); INSERT INTO employees VALUES ('{ "name": "james", "salary": 9000 }'), ('{ "name": "James", "salary": 10000 }'), ('{ "name": "Mary", "salary": 12000 }'), ('{ "name": "Peter", "salary": 8000 }'); SELECT * FROM employees WHERE CAST(data->>'$.name' AS CHAR(30)) = 'James';
CAST()
returns a string with collation utf8mb4_0900_ai_ci
, so the comparison case-insensitive and two rows match:CAST()
返回排序规则为utf8mb4_0900_ai_ci
的字符串,因此比较不区分大小写,两行匹配:
+------------------------------------+ | data | +------------------------------------+ | {"name": "james", "salary": 9000} | | {"name": "James", "salary": 10000} | +------------------------------------+
Be aware that although the optimizer supports automatically stripping 请注意,尽管优化器支持使用索引生成的列自动剥离CAST()
with indexed generated columns, the following approach does not work because it produces a different result with and without an index (Bug#27337092):CAST()
,但以下方法不起作用,因为它在有索引和无索引的情况下生成不同的结果(Bug#27337092):
mysql>CREATE TABLE employees (
data JSON,
generated_col VARCHAR(30) AS (CAST(data->>'$.name' AS CHAR(30)))
);
Query OK, 0 rows affected, 1 warning (0.03 sec) mysql>INSERT INTO employees (data)
VALUES ('{"name": "james"}'), ('{"name": "James"}');
Query OK, 2 rows affected, 1 warning (0.01 sec) Records: 2 Duplicates: 0 Warnings: 1 mysql>SELECT * FROM employees WHERE data->>'$.name' = 'James';
+-------------------+---------------+ | data | generated_col | +-------------------+---------------+ | {"name": "James"} | James | +-------------------+---------------+ 1 row in set (0.00 sec) mysql>ALTER TABLE employees ADD INDEX idx (generated_col);
Query OK, 0 rows affected, 1 warning (0.03 sec) Records: 0 Duplicates: 0 Warnings: 1 mysql>SELECT * FROM employees WHERE data->>'$.name' = 'James';
+-------------------+---------------+ | data | generated_col | +-------------------+---------------+ | {"name": "james"} | james | | {"name": "James"} | James | +-------------------+---------------+ 2 rows in set (0.01 sec)
A UNIQUE
index creates a constraint such that all values in the index must be distinct. UNIQUE
索引会创建一个约束,使得索引中的所有值都必须是不同的。An error occurs if you try to add a new row with a key value that matches an existing row. 如果尝试添加键值与现有行匹配的新行,则会发生错误。If you specify a prefix value for a column in a 如果为UNIQUE
index, the column values must be unique within the prefix length. UNIQUE
索引中的列指定前缀值,则列值在前缀长度内必须唯一。A 唯一索引允许包含UNIQUE
index permits multiple NULL
values for columns that can contain NULL
.NULL
的列具有多个NULL
值。
If a table has a 如果表的PRIMARY KEY
or UNIQUE NOT NULL
index that consists of a single column that has an integer type, you can use _rowid
to refer to the indexed column in SELECT
statements, as follows:PRIMARY KEY
(主键)或UNIQUE NOT NULL
索引由一个整型列组成,则可以使用_rowid
在SELECT
语句中引用索引列,如下所示:
如果存在由单个整数列组成的主键,则_rowid
refers to the PRIMARY KEY
column if there is a PRIMARY KEY
consisting of a single integer column. _rowid
指PRIMARY KEY
列。If there is a 如果存在PRIMARY KEY
but it does not consist of a single integer column, _rowid
cannot be used.PRIMARY KEY
,但它不包含单个整数列,则不能使用_rowid
。
Otherwise, 否则,_rowid
refers to the column in the first UNIQUE NOT NULL
index if that index consists of a single integer column. _rowid
引用第一个UNIQUE NOT NULL
索引中的列(如果该索引由单个整数列组成)。If the first 如果第一个UNIQUE NOT NULL
index does not consist of a single integer column, _rowid
cannot be used.UNIQUE NOT NULL
索引不包含单个整数列,则不能使用_rowid
。
只有FULLTEXT
indexes are supported only for InnoDB
and MyISAM
tables and can include only CHAR
, VARCHAR
, and TEXT
columns. InnoDB
和MyISAM
表支持FULLTEXT
索引,并且只能包含CHAR
列、VARCHAR
列和TEXT
列。Indexing always happens over the entire column; column prefix indexing is not supported and any prefix length is ignored if specified. 索引总是发生在整个列上;不支持列前缀索引,如果指定,则忽略任何前缀长度。See Section 12.10, “Full-Text Search Functions”, for details of operation.有关操作的详细信息,请参阅第12.10节,“全文搜索函数”。
As of MySQL 8.0.17, 从MySQL 8.0.17开始,InnoDB
supports multi-valued indexes. InnoDB
支持多值索引。A multi-valued index is a secondary index defined on a column that stores an array of values. 多值索引是在存储值数组的列上定义的二级索引。A “normal” index has one index record for each data record (1:1). “正常”索引对每个数据记录有一个索引记录(1:1)。A multi-valued index can have multiple index records for a single data record (N:1). 对于单个数据记录(N:1),多值索引可以有多个索引记录。Multi-valued indexes are intended for indexing 多值索引用于索引JSON
arrays. JSON
数组。For example, a multi-valued index defined on the array of zip codes in the following JSON document creates an index record for each zip code, with each index record referencing the same data record.例如,在下面的JSON文档中,在邮政编码数组上定义的多值索引为每个邮政编码创建一个索引记录,每个索引记录引用相同的数据记录。
{ "user":"Bob", "user_id":31, "zipcode":[94477,94536] }
You can create a multi-valued index in a 您可以在CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
statement. CREATE TABLE
、ALTER TABLE
或CREATE INDEX
语句中创建多值索引。This requires using 这需要在索引定义中使用CAST(... AS ... ARRAY)
in the index definition, which casts same-typed scalar values in a JSON
array to an SQL data type array. CAST(... AS ... ARRAY)
,它将JSON
数组中相同类型的标量值强制转换为SQL数据类型数组。A virtual column is then generated transparently with the values in the SQL data type array; finally, a functional index (also referred to as a virtual index) is created on the virtual column. 然后使用SQL数据类型数组中的值透明地生成一个虚拟列;最后,在虚拟列上创建一个函数索引(也称为虚拟索引)。It is the functional index defined on the virtual column of values from the SQL data type array that forms the multi-valued index.它是在构成多值索引的SQL数据类型数组的虚拟值列上定义的函数索引。
The examples in the following list show the three different ways in which a multi-valued index 下表中的示例显示了三种不同的方法,可以在名为zips
can be created on an array $.zipcode
on a JSON
column custinfo
in a table named customers
. customers
的表中JSON
列custinfo
上的数组$.zipcode
上创建多值索引zips
。In each case, the JSON array is cast to an SQL data type array of 在每种情况下,JSON数组都转换为无符号整数值的SQL数据类型数组。UNSIGNED
integer values.
仅用于CREATE TABLE
only:CREATE TABLE
:
CREATE TABLE customers ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, custinfo JSON, INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) ) );
兼用于CREATE TABLE
plus ALTER TABLE
:CREATE TABLE
和ALTER TABLE
:
CREATE TABLE customers ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, custinfo JSON ); ALTER TABLE customers ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );
兼用于CREATE TABLE
plus CREATE INDEX
:CREATE TABLE
和CREATE INDEX
CREATE TABLE customers ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, custinfo JSON ); CREATE INDEX zips ON customers ( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );
A multi-valued index can also be defined as part of a composite index. 多值索引也可以定义为复合索引的一部分。This example shows a composite index that includes two single-valued parts (for the 此示例显示了一个复合索引,其中包括两个单值部分(用于id
and modified
columns), and one multi-valued part (for the custinfo
column):id
列和modified
列)和一个多值部分(用于custinfo
列):
CREATE TABLE customers ( id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, custinfo JSON ); ALTER TABLE customers ADD INDEX comp(id, modified, (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );
Only one multi-valued key part can be used in a composite index. 复合索引中只能使用一个多值键部分。The multi-valued key part may be used in any order relative to the other parts of the key. 多值密钥部分可以相对于密钥的其他部分以任何顺序使用。In other words, the 换句话说,刚才显示的ALTER TABLE
statement just shown could have used comp(id, (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY), modified))
(or any other ordering) and still have been valid.ALTER TABLE
语句可能使用了comp(id, (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY), modified))
(或任何其他排序),并且仍然有效。
The optimizer uses a multi-valued index to fetch records when the following functions are specified in a 当WHERE
clause:WHERE
子句中指定以下函数时,优化器使用多值索引来获取记录:
We can demonstrate this by creating and populating the 我们可以通过使用以下customers
table using the following CREATE TABLE
and INSERT
statements:CREATE TABLE
和INSERT
语句创建和填充customers
表来演示这一点:
mysql>CREATE TABLE customers (
->id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
->modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
->custinfo JSON
->);
Query OK, 0 rows affected (0.51 sec) mysql>INSERT INTO customers VALUES
->(NULL, NOW(), '{"user":"Jack","user_id":37,"zipcode":[94582,94536]}'),
->(NULL, NOW(), '{"user":"Jill","user_id":22,"zipcode":[94568,94507,94582]}'),
->(NULL, NOW(), '{"user":"Bob","user_id":31,"zipcode":[94477,94507]}'),
->(NULL, NOW(), '{"user":"Mary","user_id":72,"zipcode":[94536]}'),
->(NULL, NOW(), '{"user":"Ted","user_id":56,"zipcode":[94507,94582]}');
Query OK, 5 rows affected (0.07 sec) Records: 5 Duplicates: 0 Warnings: 0
First we execute three queries on the 首先,我们在customers
table, one each using MEMBER OF()
, JSON_CONTAINS()
, and JSON_OVERLAPS()
, with the result from each query shown here:customers
表上执行三个查询,每个查询使用MEMBER OF()
、JSON_CONTAINS()
和JSON_OVERLAPS()
,每个查询的结果如下所示:
mysql>SELECT * FROM customers
->WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+---------------------+-------------------------------------------------------------------+ | id | modified | custinfo | +----+---------------------+-------------------------------------------------------------------+ | 2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} | | 3 | 2019-06-29 22:23:12 | {"user": "Bob", "user_id": 31, "zipcode": [94477, 94507]} | | 5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]} | +----+---------------------+-------------------------------------------------------------------+ 3 rows in set (0.00 sec) mysql>SELECT * FROM customers
->WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+---------------------+-------------------------------------------------------------------+ | id | modified | custinfo | +----+---------------------+-------------------------------------------------------------------+ | 2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} | | 5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]} | +----+---------------------+-------------------------------------------------------------------+ 2 rows in set (0.00 sec) mysql>SELECT * FROM customers
->WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+---------------------+-------------------------------------------------------------------+ | id | modified | custinfo | +----+---------------------+-------------------------------------------------------------------+ | 1 | 2019-06-29 22:23:12 | {"user": "Jack", "user_id": 37, "zipcode": [94582, 94536]} | | 2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} | | 3 | 2019-06-29 22:23:12 | {"user": "Bob", "user_id": 31, "zipcode": [94477, 94507]} | | 5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]} | +----+---------------------+-------------------------------------------------------------------+ 4 rows in set (0.00 sec)
Next, we run 接下来,我们对前面三个查询中的每一个都运行EXPLAIN
on each of the previous three queries:EXPLAIN
:
mysql>EXPLAIN SELECT * FROM customers
->WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql>EXPLAIN SELECT * FROM customers
->WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql>EXPLAIN SELECT * FROM customers
->WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | ALL | NULL | NULL | NULL | NULL | 5 | 100.00 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.01 sec)
None of the three queries just shown are able to use any keys. 刚才显示的三个查询都不能使用任何键。To solve this problem, we can add a multi-valued index on the 为了解决这个问题,我们可以在zipcode
array in the JSON
column (custinfo
), like this:JSON
列(custinfo
)中的zipcode
数组上添加一个多值索引,如下所示:
mysql>ALTER TABLE customers
->ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );
Query OK, 0 rows affected (0.47 sec) Records: 0 Duplicates: 0 Warnings: 0
When we run the previous 当我们再次运行前面的EXPLAIN
statements again, we can now observe that the queries can (and do) use the index zips
that was just created:EXPLAIN
语句时,我们现在可以观察到查询可以(并且确实)使用刚刚创建的索引zips
:
mysql>EXPLAIN SELECT * FROM customers
->WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | ref | zips | zips | 9 | const | 1 | 100.00 | Using where | +----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql>EXPLAIN SELECT * FROM customers
->WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | range | zips | zips | 9 | NULL | 6 | 100.00 | Using where | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql>EXPLAIN SELECT * FROM customers
->WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | range | zips | zips | 9 | NULL | 6 | 100.00 | Using where | +----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.01 sec)
A multi-valued index can be defined as a unique key. If defined as a unique key, attempting to insert a value already present in the multi-valued index returns a duplicate key error. 多值索引可以定义为唯一键。如果定义为唯一键,尝试插入多值索引中已存在的值将返回重复键错误。If duplicate values are already present, attempting to add a unique multi-valued index fails, as shown here:如果已经存在重复值,则尝试添加唯一的多值索引失败,如下所示:
mysql>ALTER TABLE customers DROP INDEX zips;
Query OK, 0 rows affected (0.55 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql>ALTER TABLE customers
->ADD UNIQUE INDEX zips((CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)));
ERROR 1062 (23000): Duplicate entry '[94507, ' for key 'customers.zips' mysql>ALTER TABLE customers
->ADD INDEX zips((CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)));
Query OK, 0 rows affected (0.36 sec) Records: 0 Duplicates: 0 Warnings: 0
Multi-valued indexes have the additional characteristics listed here:多值索引具有以下列出的其他特征:
DML operations that affect multi-valued indexes are handled in the same way as DML operations that affect a normal index, with the only difference being that there may be more than one insert or update for a single clustered index record.影响多值索引的DML操作的处理方式与影响普通索引的DML操作相同,唯一的区别是单个聚集索引记录可能有多个插入或更新。
Nullability and multi-valued indexes:可空性和多值索引:
If multi-valued key part has an empty array, no entries are added to the index, and the data record is not accessible by an index scan.如果多值键部分具有空数组,则不会向索引中添加任何条目,并且索引扫描无法访问数据记录。
If multi-valued key part generation returns a 如果多值密钥部分生成返回NULL
value, a single entry containing NULL
is added to the multi-valued index. NULL
值,则将向多值索引添加一个包含NULL
值的条目。If the key part is defined as 如果密钥部分定义为NOT NULL
, an error is reported.NOT NULL
,则会报告错误。
If the typed array column is set to 如果类型化数组列设置为NULL
, the storage engine stores single record containing NULL
that points to the data record.NULL
,存储引擎将存储一条包含NULL
的记录,该记录指向数据记录。
索引数组中不允许JSON
null values are not permitted in indexed arrays. JSON
空值。If any returned value is 如果任何返回值为NULL
, it is treated as a JSON null and an Invalid JSON value error is reported.NULL
,则将其视为JSON NULL
,并报告无效JSON值错误。
Because multi-valued indexes are virtual indexes on virtual columns, they must adhere to the same rules as secondary indexes on virtual generated columns.由于多值索引是虚拟列上的虚拟索引,因此它们必须遵守与虚拟生成列上的辅助索引相同的规则。
Index records are not added for empty arrays.不为空数组添加索引记录。
Multi-valued indexes are subject to the limitations and restrictions listed here:多值索引受以下限制和限制:
Only one multi-valued key part is permitted per multi-valued index. 每个多值索引只允许一个多值键部分。However, the 然而,CAST(... AS ... ARRAY)
expression can refer to multiple arrays within a JSON
document, as shown here:CAST(... AS ... ARRAY)
表达式可以引用JSON
文档中的多个数组,如下所示:
CAST(data->'$.arr[*][*]' AS UNSIGNED ARRAY)
In this case, all values matching the JSON expression are stored in the index as a single flat array.在本例中,所有与JSON表达式匹配的值都作为单个平面数组存储在索引中。
An index with a multi-valued key part does not support ordering and therefore cannot be used as a primary key. 具有多值键部分的索引不支持排序,因此不能用作主键。For the same reason, a multi-valued index cannot be defined using the 出于同样的原因,不能使用ASC
or DESC
keyword.ASC
或DESC
关键字定义多值索引。
A multi-valued index cannot be a covering index.多值索引不能是覆盖索引。
The maximum number of values per record for a multi-valued index is determined by the amount of data than can be stored on a single undo log page, which is 65221 bytes (64K minus 315 bytes for overhead), which means that the maximum total length of key values is also 65221 bytes. 多值索引的每条记录的最大值数由单个撤消日志页上可存储的数据量确定,即65221字节(64K减去315字节的开销),这意味着键值的最大总长度也是65221字节。The maximum number of keys depends on various factors, which prevents defining a specific limit. 最大键数取决于各种因素,这些因素会阻止定义特定的限制。Tests have shown a multi-valued index to permit as many as 1604 integer keys per record, for example. 例如,测试显示多值索引允许每个记录最多1604个整数键。When the limit is reached, an error similar to the following is reported: 当达到限值时,将报告类似于以下内容的错误:ERROR 3905 (HY000): Exceeded max number of values per record for multi-valued index 'idx' by 1 value(s).
The only type of expression that is permitted in a multi-valued key part is a 多值键部分中唯一允许的表达式类型是JSON
expression. JSON
表达式。The expression need not reference an existing element in a JSON document inserted into the indexed column, but must itself be syntactically valid.表达式无需引用插入索引列的JSON文档中的现有元素,但其本身必须在语法上有效。
Because index records for the same clustered index record are dispersed throughout a multi-valued index, a multi-valued index does not support range scans or index-only scans.由于同一聚集索引记录的索引记录分散在多值索引中,因此多值索引不支持范围扫描或仅索引扫描。
Multi-valued indexes are not permitted in foreign key specifications.外键规范中不允许使用多值索引。
Index prefixes cannot be defined for multi-valued indexes.无法为多值索引定义索引前缀。
Multi-valued indexes cannot be defined on data cast as 不能将多值索引定义为BINARY
(see the description of the CAST()
function).BINARY
类型转换(请参阅cast()
函数的说明)。
Online creation of a multi-value index is not supported, which means the operation uses 不支持在线创建多值索引,这意味着该操作使用ALGORITHM=COPY
. ALGORITHM=COPY
。See Performance and Space Requirements.请参阅性能和空间要求。
Character sets and collations other than the following two combinations of character set and collation are not supported for multi-valued indexes:多值索引不支持以下两种字符集和排序规则组合以外的字符集和排序规则:
The 具有默认binary
character set with the default binary
collationbinary
排序规则的binary
字符集
The 具有默认utf8mb4
character set with the default utf8mb4_0900_as_cs
collation.utf8mb4_0900_as_cs
排序规则的utf8mb4
字符集。
As with other indexes on columns of 与InnoDB
tables, a multi-valued index cannot be created with USING HASH
; attempting to do so results in a warning: This storage engine does not support the HASH index algorithm, storage engine default was used instead. InnoDB
表列上的其他索引一样,不能使用USING HASH
创建多值索引;尝试这样做会导致警告:此存储引擎不支持哈希索引算法,而是使用了存储引擎默认值。((像往常一样支持USING BTREE
is supported as usual.)USING BTREE
。)
The MyISAM
, InnoDB
, NDB
, and ARCHIVE
storage engines support spatial columns such as POINT
and GEOMETRY
. MyISAM
、InnoDB
、NDB
和ARCHIVE
存储引擎支持POINT
和GEOMETRY
等空间列。(Section 11.4, “Spatial Data Types”, describes the spatial data types.) (第11.4节,“空间数据类型”描述了空间数据类型。)However, support for spatial column indexing varies among engines. 但是,对空间列索引的支持因引擎而异。Spatial and nonspatial indexes on spatial columns are available according to the following rules.空间列上的空间索引和非空间索引根据以下规则可用。
Spatial indexes on spatial columns have these characteristics:空间列上的空间索引具有以下特征:
Available only for 仅适用于InnoDB
and MyISAM
tables. InnoDB
和MyISAM
表。Specifying 为其他存储引擎指定SPATIAL INDEX
for other storage engines results in an error.SPATIAL INDEX
会导致错误。
As of MySQL 8.0.12, an index on a spatial column must be a 从MySQL 8.0.12开始,SPATIAL
index. SPATIAL
列上的索引必须是空间索引。The 因此,SPATIAL
keyword is thus optional but implicit for creating an index on a spatial column.SPATIAL
关键字是可选的,但对于在空间列上创建索引是隐式的。
Available for single spatial columns only. 仅适用于单个空间柱。A spatial index cannot be created over multiple spatial columns.无法在多个空间列上创建空间索引。
Indexed columns must be 索引列必须为NOT NULL
.NOT NULL
。
Column prefix lengths are prohibited. 禁止使用列前缀长度。The full width of each column is indexed.每列的全宽都被索引。
Not permitted for a primary key or unique index.主键或唯一索引不允许使用。
Nonspatial indexes on spatial columns (created with 空间列上的非空间索引(使用INDEX
, UNIQUE
, or PRIMARY KEY
) have these characteristics:INDEX
、UNIQUE
或PRIMARY KEY
创建)具有以下特征:
Permitted for any storage engine that supports spatial columns except 允许任何支持空间列(ARCHIVE
.ARCHIVE
除外)的存储引擎使用。
Columns can be 除非索引是主键,否则列可以为NULL
unless the index is a primary key.NULL
。
The index type for a non-非空间索引的索引类型取决于存储引擎。SPATIAL
index depends on the storage engine. Currently, B-tree is used.目前,使用的是B-树索引。
Permitted for a column that can have 仅允许NULL
values only for InnoDB
, MyISAM
, and MEMORY
tables.InnoDB
、MyISAM
和MEMORY
表的列具有NULL
值。
Following the key part list, index options can be given. 在关键部件列表之后,可以提供索引选项。An index_option
value can be any of the following:index_option
值可以是以下任意值:
KEY_BLOCK_SIZE [=]
value
For 对于MyISAM
tables, KEY_BLOCK_SIZE
optionally specifies the size in bytes to use for index key blocks. MyISAM
表,KEY_BLOCK_SIZE
可以选择指定索引键块使用的大小(以字节为单位)。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. InnoDB
表的索引级别不支持KEY_BLOCK_SIZE
。See Section 13.1.20, “CREATE TABLE Statement”.请参阅第13.1.20节,“CREATE INDEX语句”。
index_type
Some storage engines permit you to specify an index type when creating an index. For example:某些存储引擎允许您在创建索引时指定索引类型。例如:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index ON lookup (id) USING BTREE;
Table 13.1, “Index Types Per Storage Engine” shows the permissible index type values supported by different storage engines. 表13.1,“每个存储引擎的索引类型”显示了不同存储引擎支持的允许索引类型值。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.index_type
子句。
The index_type
clause cannot be used for FULLTEXT INDEX
or (prior to MySQL 8.0.12) SPATIAL INDEX
specifications. index_type
子句不能用于FULLTEXT INDEX
或(MySQL 8.0.12之前的)SPATIAL INDEX
规范。Full-text index implementation is storage engine dependent. 全文索引实现依赖于存储引擎。Spatial indexes are implemented as R-tree indexes.空间索引实现为R树索引。
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. RTREE
识别为类型名。As of MySQL 8.0.12, this is permitted only for 从MySQL 8.0.12开始,这只允许用于SPATIAL
indexes. SPATIAL
索引。Prior to 8.0.12, 在8.0.12之前,不能为任何存储引擎指定RTREE
cannot be specified for any storage engine.RTREE
。
NDB存储引擎将BTREE
indexes are implemented by the NDB
storage engine as T-tree indexes.BTREE
索引作为T树索引实现。
For indexes on 对于NDB
table columns, the USING
option can be specified only for a unique index or primary key. NDB
表列上的索引,只能为唯一索引或主键指定USING
选项。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.USING HASH
防止创建有序索引;否则,在NDB
表上创建唯一索引或主键会自动创建有序索引和散列索引,其中每个索引都包含同一组列。
For unique indexes that include one or more 对于包含NDB表的一个或多个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. NULL
列的唯一索引,哈希索引只能用于查找文字值,这意味着IS [NOT]NULL
条件需要对表进行完整扫描。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.NULL
列的唯一索引总是以包含有序索引的方式创建;也就是说,在创建索引时避免使用USING HASH
。
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.RTREE
识别为类型名,但目前无法为任何存储引擎指定该名称。
Use of the 不推荐在index_type
option before the ON
clause is deprecated; expect support for use of the option in this position to be removed in a future MySQL release. tbl_name
ON
子句之前使用tbl_name
index_type
选项;希望在将来的MySQL版本中删除对此位置使用选项的支持。If an 如果在较早和较晚的位置都给出了index_type
option is given in both the earlier and later positions, the final option applies.index_type
选项,则最终选项适用。
TYPE
is recognized as a synonym for type_name
USING
. type_name
TYPE
被识别为使用类型名称的同义词。type_name
However, 然而,USING
is the preferred form.USING
是首选形式。
The following tables show index characteristics for the storage engines that support the 下表显示了支持index_type
option.index_type
选项的存储引擎的索引特征。
Table 13.2 InnoDB Storage Engine Index CharacteristicsInnoDB
存储引擎索引特性
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE | No | No | N/A | N/A |
Unique | BTREE | Yes | Yes | Index | Index |
Key | BTREE | Yes | Yes | Index | Index |
FULLTEXT | N/A | Yes | Yes | Table | Table |
SPATIAL | N/A | No | No | N/A | N/A |
Table 13.3 MyISAM Storage Engine Index CharacteristicsMyISAM
存储引擎索引特性
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE | No | No | N/A | N/A |
Unique | BTREE | Yes | Yes | Index | Index |
Key | BTREE | Yes | Yes | Index | Index |
FULLTEXT | N/A | Yes | Yes | Table | Table |
SPATIAL | N/A | No | No | N/A | N/A |
Table 13.4 MEMORY Storage Engine Index Characteristics内存存储引擎索引特性
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE | No | No | N/A | N/A |
Unique | BTREE | Yes | Yes | Index | Index |
Key | BTREE | Yes | Yes | Index | Index |
Primary key | HASH | No | No | N/A | N/A |
Unique | HASH | Yes | Yes | Index | Index |
Key | HASH | Yes | Yes | Index | Index |
Table 13.5 NDB Storage Engine Index CharacteristicsNDB存储引擎索引特性
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE | No | No | Index | Index |
Unique | BTREE | Yes | Yes | Index | Index |
Key | BTREE | Yes | Yes | Index | Index |
Primary key | HASH | No | No | Table (see note 1) | Table (see note 1) |
Unique | HASH | Yes | Yes | Table (see note 1) | Table (see note 1) |
Key | HASH | Yes | Yes | Table (see note 1) | Table (see note 1) |
Table note:表注:
1. USING HASH
prevents creation of an implicit ordered index.USING HASH
可以防止创建隐式有序索引。
WITH PARSER
parser_name
This option can be used only with 此选项只能用于FULLTEXT
indexes. FULLTEXT
索引。It associates a parser plugin with the index if full-text indexing and searching operations need special handling. 如果全文索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。InnoDB
and MyISAM
support full-text parser plugins. InnoDB
和MyISAM
支持全文解析器插件。If you have a 如果您有一个带有相关全文解析器插件的MyISAM
table with an associated full-text parser plugin, you can convert the table to InnoDB
using ALTER TABLE
. MyISAM
表,则可以使用ALTERTABLE将该表转换为InnoDB
。See Full-Text Parser Plugins and Writing Full-Text Parser Plugins for more information.有关更多信息,请参阅全文解析器插件和编写全文解析器插件。
COMMENT '
string
'
Index definitions can include an optional comment of up to 1024 characters.索引定义可以包含最多1024个字符的可选注释。
The 可以使用MERGE_THRESHOLD
for index pages can be configured for individual indexes using the index_option
COMMENT
clause of the CREATE INDEX
statement. CREATE INDEX
语句的index_option
COMMENT
子句为各个索引配置索引页的MERGE_THRESHOLD
。For example:例如:
CREATE TABLE t1 (id INT); CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
If the page-full percentage for an index page falls below the 当删除一行或更新操作缩短一行时,如果索引页的页面完整百分比低于MERGE_THRESHOLD
value when a row is deleted or when a row is shortened by an update operation, InnoDB
attempts to merge the index page with a neighboring index page. MERGE_THRESHOLD
,InnoDB
将尝试将索引页与相邻索引页合并。The default 默认的MERGE_THRESHOLD
value is 50, which is the previously hardcoded value.MERGE_THRESHOLD
为50,这是以前硬编码的值。
还可以使用MERGE_THRESHOLD
can also be defined at the index level and table level using CREATE TABLE
and ALTER TABLE
statements. CREATE TABLE
和ALTER TABLE
语句在索引级别和表级别定义MERGE_THRESHOLD
。For more information, see Section 15.8.11, “Configuring the Merge Threshold for Index Pages”.有关更多信息,请参阅第15.8.11节,“配置索引页的合并阈值”。
VISIBLE
, INVISIBLE
Specify index visibility. Indexes are visible by default. 指定索引可见性。默认情况下,索引是可见的。An invisible index is not used by the optimizer. 优化器不使用不可见索引。Specification of index visibility applies to indexes other than primary keys (either explicit or implicit). 索引可见性规范适用于主键以外的索引(显式或隐式)。For more information, see Section 8.3.12, “Invisible Indexes”.有关更多信息,请参阅第8.3.12节,“不可见索引”。
ENGINE_ATTRIBUTE
and SECONDARY_ENGINE_ATTRIBUTE
options (available as of MySQL 8.0.21) are used to specify index attributes for primary and secondary storage engines. ENGINE_ATTRIBUTE
和SECONDARY_ENGINE_ATTRIBUTE
选项(从MySQL 8.0.21开始提供)用于指定主存储引擎和辅助存储引擎的索引属性。The options are reserved for future use.这些选项保留供将来使用。
Permitted values are a string literal containing a valid 允许的值是包含有效JSON
document or an empty string (''). JSON
文档的字符串文字或空字符串("")。Invalid 无效的JSON
is rejected.JSON
被拒绝。
CREATE INDEX i1 ON t1 (c1) ENGINE_ATTRIBUTE='{"key
":"value
"}';
ENGINE_ATTRIBUTE
and SECONDARY_ENGINE_ATTRIBUTE
values can be repeated without error. ENGINE_ATTRIBUTE
值和SECONDARY_ENGINE_ATTRIBUTE
值可以无错误地重复。In this case, the last specified value is used.在这种情况下,将使用最后指定的值。
服务器不会检查ENGINE_ATTRIBUTE
and SECONDARY_ENGINE_ATTRIBUTE
values are not checked by the server, nor are they cleared when the table's storage engine is changed.ENGINE_ATTRIBUTE
值和SECONDARY_ENGINE_ATTRIBUTE
值,更改表的存储引擎时也不会清除这些值。
在修改表的索引时,可能会给出ALGORITHM
and LOCK
clauses may be given to influence the table copying method and level of concurrency for reading and writing the table while its indexes are being modified. ALGORITHM
和LOCK
子句来影响表复制方法和读写表的并发级别。They have the same meaning as for the 它们与ALTER TABLE
statement. ALTER TABLE
语句的含义相同。For more information, see Section 13.1.9, “ALTER TABLE Statement”有关更多信息,请参阅第13.1.9节,“ALTER TABLE语句”。
NDB Cluster supports online operations using the same NDB集群支持使用与标准MySQL服务器相同的ALGORITHM=INPLACE
syntax used with the standard MySQL Server. ALGORITHM=INPLACE
语法进行在线操作。See Section 23.5.11, “Online Operations with ALTER TABLE in NDB Cluster”, for more information.更多信息,请参阅第23.5.11节,“NDB集群中ALTER TABLE的在线操作”。