mysql> create index func_index on t3 ((UPPER(c2))); Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 (4)查看t3表上的索引信息,如下所示。
mysql> show index from t3 /G*************************** 1. row *************************** Table: t3 Non_unique: 1 Key_name: idx1 Seq_in_index: 1 Column_name: c1 Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: YES Expression: NULL*************************** 2. row *************************** Table: t3 Non_unique: 1 Key_name: func_index Seq_in_index: 1 Column_name: NULL Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: YES Expression: upper(`c2`)2 rows in set (0.01 sec) (5)查看查詢優化器對兩個索引的使用情況 首先,查看c1字段的大寫值是否等于某個特定的值,如下所示。
mysql> explain select * from t3 where upper(c1) = 'ABC' /G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: t3 partitions: NULL type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1 filtered: 100.00 Extra: Using where1 row in set, 1 warning (0.00 sec) 可以看到,沒有使用索引,進行了全表掃描操作。
接下來,查看c2字段的大寫值是否等于某個特定的值,如下所示。
mysql> explain select * from t3 where upper(c2) = 'ABC' /G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: t3 partitions: NULL type: ref possible_keys: func_index key: func_index key_len: 43 ref: const rows: 1 filtered: 100.00 Extra: NULL1 row in set, 1 warning (0.00 sec) 可以看到,使用了函數索引。
(6)函數索引對JSON數據的索引 首先,創建測試表emp,并對JSON數據進行索引,如下所示。
mysql> create table if not exists emp(data json, index((CAST(data->>'$.name' as char(30))))); Query OK, 0 rows affected (0.02 sec) 上述SQL語句的解釋如下:
JSON數據長度不固定,如果直接對JSON數據進行索引,可能會超出索引長度,通常,會只截取JSON數據的一部分進行索引。 CAST()類型轉換函數,把數據轉化為char(30)類型。使用方式為CAST(數據 as 數據類型)。 data ->> '$.name’表示JSON的運算符 簡單的理解為,就是取name節點的值,將其轉化為char(30)類型。
接下來,查看emp表中的索引情況,如下所示。
mysql> show index from emp /G *************************** 1. row *************************** Table: emp Non_unique: 1 Key_name: functional_index Seq_in_index: 1 Column_name: NULL Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: Visible: YES Expression: cast(json_unquote(json_extract(`data`,_utf8mb4/'$.name/')) as char(30) charset utf8mb4) 1 row in set (0.00 sec) (7)函數索引基于虛擬列實現 首先,查看t3表的信息,如下所示。
mysql> desc t3; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | varchar(10) | YES | MUL | NULL | | | c2 | varchar(10) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.00 sec) 在c1上建立了普通索引,在c2上建立了函數索引。
接下來,在t3表中添加一列c3,模擬c2上的函數索引,如下所示。
mysql> alter table t3 add column c3 varchar(10) generated always as (upper(c1)); Query OK, 0 rows affected (0.03 sec) Records: 0 Duplicates: 0 Warnings: 0 c3列是一個計算列,c3字段的值總是使用c1字段轉化為大寫的結果。